> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: Agent Studio graph and custom-tool validation

> Decode the graph-publish and custom-tool registration codes — GRAPH_VALIDATION_FAILED, GRAPH_TOOL_NODES_NOT_SUPPORTED_IN_TEST_RUN, RESERVED_TOOL_NAME, TOOL_NAME_TAKEN, TOOL_DISABLED, INVALID_EXECUTOR_URL, TOOL_IMPL_NOT_REGISTERED, INVALID_HANDOFF_TARGETS, INVALID_KNOWLEDGE_BASE_IDS, and LEGACY_KB_DOC_NOT_RECHUNKABLE — fix the gate, and decide between retry and escalation.

# Troubleshooting: Agent Studio graph and custom-tool validation

The Agent Studio canvas (see [Build Agents Visually in the Agent Studio
Canvas](/guides/agent-studio-canvas)) can reject a publish or a test-run,
and the custom-tool registry rejects registration or invocation, each with
its own validation code. The runtime-error family
([agent runtime errors](/troubleshooting/agent-errors)) covers the codes
that fire mid-turn; this page owns the validation family that fires at
publish, register, or wiring time.

Every failure here arrives as a structured envelope — key on `error.code`,
and for `GRAPH_VALIDATION_FAILED` read the per-issue list in
`error.details` before you touch the canvas:

```json theme={null}
{
  "error": {
    "code": "GRAPH_VALIDATION_FAILED",
    "message": "Graph failed publish validation",
    "status": 422,
    "details": [
      "edge 7f2e1a source references missing node 'node_4'",
      "node 'collect_digits' has no outgoing edge",
      "play_prompt node 'welcome' has empty spoken text"
    ]
  },
  "meta": {
    "request_id": "req_01J04Q8K2N",
    "timestamp": "2026-09-19T10:02:14.410Z"
  }
}
```

## Graph publish validation

| Code                                         | HTTP | Cause                                                                                                                                                                                   | Fix                                                                                                                                                                                                                                       |
| -------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GRAPH_VALIDATION_FAILED`                    | 422  | The graph failed either structure validation (an edge pointing at a missing node, an empty node id, an unrecognised node kind) or publish-time semantic validation.                     | Read `error.details` — it lists one entry per failing node or edge. Fix each named node on the canvas, Save, and Deploy again. The console renders the `details` list inline on publish, so you do not have to guess which node is wrong. |
| `GRAPH_TOOL_NODES_NOT_SUPPORTED_IN_TEST_RUN` | 422  | A Tool Call node sits in the graph and the test-run endpoint was asked to execute it. Tool nodes dispatch through the MCP registry, which only the published agent's `/run` path wires. | Publish the graph, then invoke the agent's `/run` endpoint instead of the Studio test-run for a tool-node check. The response `meta` message lists the offending tool node ids.                                                           |

## Custom tool registration

These codes come from `POST /agents/custom-tools` and the invoke path
(see [Build custom tools for AI agents](/guides/agents-custom-tools)).

| Code                   | HTTP | Cause                                                                                                                                                                                                                                                                                               | Fix                                                                                                                                                    |
| ---------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `RESERVED_TOOL_NAME`   | 422  | The requested tool name collides with a built-in platform tool (like `lookup_contacts` or `send_sms`).                                                                                                                                                                                              | Rename the tool to a tenant-specific slug and re-register. Names are immutable once set, so pick the slug before any agent trains prompts on it.       |
| `TOOL_NAME_TAKEN`      | 409  | Another custom tool in the tenant already holds the requested name. The registry is tenant-wide — one tool per name.                                                                                                                                                                                | List the existing tool (`GET /agents/custom-tools`) and either rename-or-retire it, or PATCH the existing registration instead of re-creating.         |
| `TOOL_DISABLED`        | 409  | The invoke request named a tool whose `enabled` flag is off. Per-agent attach lists still name the id; the runtime skips it when the flag is off.                                                                                                                                                   | Re-enable the registry entry, then retry the invoke. Unlike versions, `enabled` is the only gate — flipping it back on resumes invocation immediately. |
| `INVALID_EXECUTOR_URL` | 422  | The `executor_url` failed the SSRF write-time guard — the same public-FQDN check webhook and MCP registrations enforce. Rejected classes: non-HTTPS scheme, loopback or private address, link-local or cloud-metadata host, internal-only hostname suffix, and DNS records that resolve internally. | Point the executor at a public HTTPS FQDN. The `failure_code` field on the envelope names the reject class.                                            |

Sample `INVALID_EXECUTOR_URL` envelope:

```json theme={null}
{
  "error": {
    "code": "INVALID_EXECUTOR_URL",
    "message": "Executor URL rejected: resolves to a private address",
    "failure_code": "private-address",
    "status": 422
  },
  "meta": {
    "request_id": "req_01J04R1V6X",
    "timestamp": "2026-09-19T10:04:52.018Z"
  }
}
```

## Tool wiring errors

These fire when a graph, registry, or agent reference points at a KB, a
handoff target, or a runtime handler that cannot resolve.

| Code                         | HTTP | Cause                                                                                                                                   | Fix                                                                                                       |
| ---------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `TOOL_IMPL_NOT_REGISTERED`   | 500  | The Orby runtime listed a tool by name but no handler was registered for it — a runtime wiring fault, not a tenant mistake.             | Escalate with the `request_id` from `meta`; support can trace which registry entry the executor resolved. |
| `INVALID_HANDOFF_TARGETS`    | 422  | The `handoff_targets` list on an agent names agents that do not exist in the tenant.                                                    | The message lists the bad ids. Remove the stale agents or correct the ids, then re-submit.                |
| `INVALID_KNOWLEDGE_BASE_IDS` | 422  | `knowledge_base_ids` names KBs that do not resolve in this tenant — usually a stale id pasted from another agent or a knackered KB row. | The message lists the bad ids. Replace them with live KB ids, then re-submit.                             |

## KB re-chunking

| Code                            | HTTP | Cause                                                                                                                                                                                                                               | Fix                                                                                                                                            |
| ------------------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `LEGACY_KB_DOC_NOT_RECHUNKABLE` | 409  | The **Re-chunk this doc** action (or `POST /agents/:id/knowledge-base/:docId/rechunk`) ran against a document uploaded through the legacy knowledge-base flow, which has no rewriteable chunk rows for the modern embeddings model. | Re-upload the document through the canonical KB flow — see [Knowledge base document inspector](/agents/kb-document-inspector) — then re-chunk. |

## Decision checklist

Run this after any of the codes above:

1. Read `error.code` on the envelope.
2. If it is one of the deterministic 422s (`GRAPH_VALIDATION_FAILED`,
   `GRAPH_TOOL_NODES_NOT_SUPPORTED_IN_TEST_RUN`, `RESERVED_TOOL_NAME`,
   `INVALID_EXECUTOR_URL`-family reject classes,
   `INVALID_HANDOFF_TARGETS`, `INVALID_KNOWLEDGE_BASE_IDS`) — do NOT
   retry; fix the payload, the graph, or the registry first.
3. If it is `TOOL_NAME_TAKEN` or `TOOL_DISABLED` — clear the collision or
   re-enable the tool, then retry.
4. If it is `TOOL_IMPL_NOT_REGISTERED` — treat as a runtime fault; do not
   retry and escalate.
5. For `GRAPH_VALIDATION_FAILED`, scan `error.details` for the exact
   node/edge and fix on the canvas; the console prints the same list
   inline.

## What NOT to do

* **Do not retry `GRAPH_VALIDATION_FAILED` in a loop.** The graph is
  invalid; a retry re-runs the same gate.
* **Do not rename a custom tool to work around `TOOL_NAME_TAKEN`.** The
  name is the id the LLM sees and every attached agent trains prompts on
  it; renaming after the fact breaks trained prompts. Rename the
  duplicate target instead.
* **Do not point `executor_url` at an internal host with a public
  alias.** DNS resolution runs at write time and again at dispatch, so a
  public-looking hostname that resolves internally still fails.
* **Do not escalate on `TOOL_NAME_TAKEN` / `TOOL_DISABLED` /
  `INVALID_HANDOFF_TARGETS` / `INVALID_KNOWLEDGE_BASE_IDS` / the 422
  validation codes.** These are deterministic tenant-owned gates.
  Escalate only `TOOL_IMPL_NOT_REGISTERED` (500) with `request_id`.
* **Do not retry the re-chunk on a legacy document.** Re-upload through
  the canonical KB flow first; the 409 is deterministic.

## When to escalate

Escalate to support **only** for `TOOL_IMPL_NOT_REGISTERED` (500) — the
`request_id` from `meta` lets support trace which registry entry the
executor resolved. Everything else on this page is a deterministic
tenant-side fix.

## See also

* [Build Agents Visually in the Agent Studio
  Canvas](/guides/agent-studio-canvas) — the canvas that owns the graph
  validations.
* [Build custom tools for AI
  agents](/guides/agents-custom-tools) — the registry this page's
  codes come from.
* [Agent runtime errors](/troubleshooting/agent-errors) — the sibling
  runbook for mid-turn codes.
* [Knowledge base document
  inspector](/agents/kb-document-inspector) — the re-chunk action and
  its version lineage.
* [Error code reference](/reference/error-codes) — the full catalog
  this page maps.
