# Troubleshooting

Common errors and the fastest fix. Scan the table for your symptom, jump to the section for context.

| Symptom | Likely cause | Fix |
| ------- | ------------ | --- |
| `401` / `403` on a webhook call | Wrong / missing bearer token, or trigger requires auth but no secret set | Check the Webhook node's **Auth** config and the header you send |
| Agent returns `"{}"` with JSON schema enabled | No input flowed into the node | Check the trigger payload and the wiring upstream |
| Image generation: `400 Unknown parameter` | Model / parameter mismatch on the provider side | Auto-retried with the corrected payload — if it persists, change model |
| Credential can't be read (`404` on decrypt) | The stored credential became unreadable | Recreate the credential; if it persists, contact support |
| Shell tool: `command not found` | Binary isn't in the sandbox image | Add it to the sandbox image, or call a different tool |
| `429` on `/execute/start` | Per-user run quota hit | Wait for the window to roll over, or upgrade |
| Trigger fires but workflow input is empty | Trigger config wrong, or dedupe key collapsed the event | Inspect the Runs tab; re-check trigger config + dedupe key |
| `400` when saving the workflow | A structural rule is violated (2 triggers, trigger + Start, unauthenticated webhook, Respond misuse) | Read the error; fix the entry point / Respond node |
| Workflow Doctor flags a deprecated node | The workflow uses a node type that the registry marks as deprecated | Apply the suggested migration, or replace it manually with the recommended node |
| Can't switch a workflow to **Live** | A node isn't runnable yet (Agent without instructions, HTTP without URL, …) | Open the flagged node and fill the missing field |

## Webhook returns 401 or 403

The Webhook trigger fails closed. If `authType` is anything other than `none` and no secret is configured, every call returns `401`.

- **`401 Invalid webhook credentials`** — Header is missing, malformed, or doesn't match the configured secret. Send exactly:
  - `Authorization: Bearer <token>` for `bearerSecret`
  - The configured header name (default `X-API-Key: <token>`) for `apiKeySecret`
- **`403`** on a published-API call — Either the API surface is disabled, the agent is inactive, or the agent key was revoked. Check the Production space → Deploy → API → key list.

## Agent returns "{}" or empty JSON

When an Agent has **structured output (JSON schema)** enabled and downstream fields are empty, the input never reached the model.

- Confirm the trigger actually fired (Runs tab → expand the row → **Input** block).
- If the trigger's input has the data, but the Agent shows `{}` — your **input template** in the Agent likely references a path that doesn't exist. Use **Test with fixture** in the editor and watch the resolved prompt.
- If the model returned text but it doesn't match the schema, the run will fail with a schema-validation error (not silent `{}`).

## Image generation: 400 "Unknown parameter"

You'll see this if the model/provider doesn't accept a parameter from a different API version (e.g. `response_format` on a model that uses `output_format`).

The executor retries once with the corrected payload — most of the time you'll only see the error in the logs, never on the run. If it persists:

- Switch model in the node config.
- Check the provider's current parameter list.
- File a bug — we keep the parameter map updated.

## Credential can't be read (404 on decrypt)

A stored credential has become unreadable. Symptoms:

- Nodes that worked before now show "credential not found".

Fix:

1. Open the Credentials page.
2. Delete the affected credential.
3. Recreate it (same name) with the secret.
4. Re-run.

If recreating the credential doesn't resolve it, contact support with your `run_id`.

## Shell tool: "command not found"

The sandbox runs a minimal Alpine-based image. `bash`, `curl`, `jq`, `python3` are present; `node`, `gcc`, exotic CLIs are not.

Options:

- Add the binary to your sandbox image (`apk add <pkg>`) and rebuild.
- Use the Code Interpreter tool instead — it has Python + numpy/pandas/requests preinstalled.
- Rewrite the step as an HTTP request to a service that already has the binary.

Never disable the sandbox to "fix" this. The sandbox is a security boundary, not a CI nuisance.

## 429 on /execute/start

Per-user execution quota was hit. The response includes a `Retry-After` header (seconds) and a JSON body:

```json
{ "detail": "Execution quota exceeded. Try again in 312s." }
```

Fix:

- Wait for the window to roll over.
- Reduce trigger frequency (Schedule node's cron, or webhook dedupe).
- Upgrade your plan.
- For a runaway loop, kill the offending run from the **Production** tab (Cancel).

## Trigger fired but workflow input is empty

Two common causes:

1. **Trigger config doesn't extract the right field.** Open the trigger node, hit **Fetch real event**, look at the live payload. Make sure your **input mapping** (or template) references a path that exists.
2. **Dedupe key collapsed the event.** Triggers (especially Gmail, Notion, HTTP poll) maintain a dedupe set so the same event doesn't fire twice. If you re-pointed the trigger at a new source but kept the old dedupe key, brand-new events look "already seen".

Fix:

- Bump the dedupe key (any change resets the set).
- Or clear the trigger's dedupe state from the **Production** tab.

## 400 when saving the workflow

Saving runs structural validation. A blocking rule returns `400` and the workflow isn't saved. The message names the rule; the usual culprits:

- **More than one trigger node.** A workflow has exactly one entry — keep a single Webhook / Schedule / Event listener.
- **A trigger node mixed with a Start node.** Pick one entry point: a published trigger *or* a manual/API Start, not both.
- **Webhook with `authType: none`, or no path.** Webhooks must be authenticated and have a path — set an auth type (bearer / API key) and a route.
- **Respond node misused.** Only one Respond node is allowed, and only with a Webhook trigger or a Start entry. With a Schedule or Event listener trigger there's no caller to answer, so it's rejected.

An **orphan node** (no incoming connection and not the entry) is only a **warning** — it saves, but that node never runs. Wire it up or delete it. See [Validation rules](#/concepts).

## Workflow Doctor flags a deprecated node

Deprecated nodes still appear in older workflows, but should not be used for new work. Workflow Doctor reads compatibility metadata from the node registry and reports deprecated node types as warnings.

Fix:

- Use the migration action when Workflow Doctor offers one.
- If no automatic migration is available, replace the node with the recommended successor and rewire the same inputs and outputs.
- Save a version before migrating so you can compare or restore the previous graph.

## Can't activate / go Live

New workflows start as **Draft**. Switching to **Live** runs an activation check: every node must be runnable. The toggle is blocked, and the offending node is flagged, when:

- An **Agent** has no instructions (empty system prompt).
- An **HTTP Request** has no URL.
- A **Send Email** has no recipient.
- A **Sub-workflow** has no target workflow selected.

Fix:

1. Open the flagged node.
2. Fill the missing field (system prompt / URL / recipient / target).
3. Save, then flip to **Live** again.

This is separate from save-time structural validation above — a workflow can save fine as Draft yet still be incomplete to run.

## Sandbox isolation

`Shell` and `Code Interpreter` run in an isolated sandbox enforced by the platform — each call gets an ephemeral environment with no access to host paths, other users' data, or cloud metadata. You don't configure this; it's always on.

If a sandboxed tool ever appears to see something it shouldn't, contact support with your `run_id`.

## Still stuck

- **Runs tab** is your friend — every run records input, output, error, and the exact node that failed (`failed_node_label`).
- For platform-level issues, check the platform status page or contact support with your `run_id`.

---

*Source: https://agentbuilder.systalink.sn/docs/troubleshooting — human documentation.*
*Other language: [/docs-md/fr/troubleshooting.md](/docs-md/fr/troubleshooting.md).*
*Machine-readable index: [/llms.txt](/llms.txt).*
