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

# Error Codes

> Every failure mode the runtime surfaces, what triggers it, and what the AI is told.

When an invocation can't complete, the runtime returns a structured error to the AI (so the conversation keeps moving) and logs the same code to the **Invocations** panel (so you can grep your way to a fix).

## The shape

Every error response from our runtime has the same JSON body:

```json theme={null}
{
  "ok": false,
  "error_code": "HTTP_TOOL_TIMEOUT",
  "error_message": "Endpoint timed out after 10s.",
  "llm_message": "Lookup timed out. Let me continue without it.",
  "invocation_id": "1234..."
}
```

| Field           | Use                                                                                          |
| --------------- | -------------------------------------------------------------------------------------------- |
| `ok`            | Always `false` on errors.                                                                    |
| `error_code`    | Stable, machine-readable. Use it for alerting / log filters.                                 |
| `error_message` | Short, customer-facing English. Shown in the dashboard row.                                  |
| `llm_message`   | What the AI receives as the "tool result", phrased so it can keep talking naturally.         |
| `invocation_id` | UUID of the matching row in `http_tool_invocations`. Click into the row to see full details. |

## Full catalog

<ResponseField name="HTTP_TOOL_NOT_FOUND" type="404 / 400">
  **When:** the tool doesn't exist, belongs to another tenant, or has been deleted (a deleted tool is filtered out and reads as not-found, not "inactive"). This is a common symptom of a stale agent config that still references a tool you removed. Also returned at HTTP 400 when the request arrives with a missing `tenant_id` or `tool_id`.

  **error\_message:** Tool not found.

  **llm\_message:** I couldn't find that lookup. Let me continue.

  **Fix:** Check the tool still exists, isn't deleted, and is on the same tenant as the agent.
</ResponseField>

<ResponseField name="HTTP_TOOL_INACTIVE" type="404">
  **When:** the tool exists but its `is_active` flag is off. That's the only trigger, a *deleted* tool returns `HTTP_TOOL_NOT_FOUND` instead.

  **error\_message:** Tool is disabled.

  **llm\_message:** That lookup isn't currently available.

  **Fix:** Re-enable the tool in the manager.
</ResponseField>

<ResponseField name="HTTP_TOOL_ADDON_INACTIVE" type="403">
  **When:** the tenant doesn't have the Power Tools add-on active.

  **error\_message:** Power Tools add-on is not active for this tenant.

  **llm\_message:** Custom lookups aren't enabled here.

  **Fix:** Add the Power Tools add-on under Account → Billing. The tool descriptor is also hidden from the agent's tool list, so the LLM shouldn't even try, if it does, the runtime fails closed.
</ResponseField>

<ResponseField name="HTTP_TOOL_INVALID_ARGS" type="400">
  **When:** the LLM called the tool with arguments that don't match `parameters_schema`. The LLM usually corrects itself and tries again.

  **error\_message:** Arguments don't match the tool's schema: `<field>: <message>`.

  **llm\_message:** Let me try those arguments differently.

  **Fix:** If you see this code firing repeatedly, your description is probably leading the LLM into an invalid shape. Tighten the description or relax the schema.
</ResponseField>

<ResponseField name="HTTP_TOOL_URL_BLOCKED" type="502">
  **When:** SSRF guard rejected the URL at invocation time, usually DNS rebinding (host validated fine at save, now resolves to a private IP). See [Security restrictions](/guides/http-tools/security-restrictions).

  **error\_message:** URL resolves to a blocked network.

  **llm\_message:** I couldn't reach that lookup target.

  **Fix:** Check what your hostname resolves to. If you genuinely run on a public IP and we still block, [open a support ticket](mailto:hello@aisky.co.za) with the resolved IP.
</ResponseField>

<ResponseField name="HTTP_TOOL_TIMEOUT" type="504">
  **When:** the full request (TLS handshake + DNS + your server + response) exceeded 10 seconds.

  **error\_message:** Endpoint timed out after 10s.

  **llm\_message:** Lookup timed out. Let me continue without it.

  **Fix:** Profile your endpoint. Aim for sub-2-second responses for the smoothest call experience. If you need longer-running work, return a "still processing" hint and have the AI ask the caller to hold.
</ResponseField>

<ResponseField name="HTTP_TOOL_CONNECTION_FAILED" type="502">
  **When:** DNS resolution failed, TCP connection refused, TLS handshake failed, or the connection dropped mid-stream.

  **error\_message:** Couldn't connect to endpoint: `<reason>`.

  **llm\_message:** I couldn't reach the lookup service.

  **Fix:** Verify your endpoint is up. Check TLS certificate validity (expired certs are a common cause). Confirm DNS resolves correctly from the public internet.
</ResponseField>

<ResponseField name="HTTP_TOOL_TOO_MANY_REDIRECTS" type="502">
  **When:** your endpoint returned a 3xx redirect. We don't follow redirects, your URL must resolve directly to the handler.

  **error\_message:** Endpoint redirected too many times.

  **llm\_message:** The lookup service is misconfigured. Continuing without it.

  **Fix:** Resolve the final URL yourself and update the tool's endpoint to point straight at it.
</ResponseField>

<ResponseField name="HTTP_TOOL_INVALID_RESPONSE_TYPE" type="502">
  **When:** your endpoint returned `application/octet-stream` or another binary content type.

  **error\_message:** Endpoint returned unsupported content-type: `<ct>`.

  **llm\_message:** Lookup returned an unsupported format.

  **Fix:** Return `application/json` or any `text/*` content type. The AI can't speak binary blobs.
</ResponseField>

<ResponseField name="HTTP_TOOL_RESPONSE_TOO_LARGE" type="200">
  **When:** your response body exceeded 64 KB. This is **not** a hard error, we truncate and still pass the first 64 KB to the AI with a `[truncated]` footer. It's flagged in the invocations log so you know.

  **error\_message:** Response was N bytes; truncated to 65536.

  **llm\_message:** Lookup returned a large response; I'll work with the first part.

  **Fix:** Design responses to fit in 4 KB ideally. The AI doesn't summarize huge blobs reliably.
</ResponseField>

<ResponseField name="HTTP_TOOL_CUSTOMER_ERROR" type="502">
  **When:** your endpoint returned a 4xx or 5xx status code.

  **error\_message:** Endpoint returned `<status>`.

  **llm\_message:** The lookup service returned an error. Continuing.

  **Fix:** Check your endpoint logs. Often this means your auth check failed (the Bearer token in the tool config doesn't match what your server expects) or your code path hit an unhandled exception.
</ResponseField>

<ResponseField name="HTTP_TOOL_RATE_LIMITED" type="429">
  **When:** the per-tenant (60/min) or per-tool (30/min) token bucket has emptied. See [Rate limits](/guides/http-tools/rate-limits).

  **error\_message:** Rate limit exceeded (60/min tenant) or (30/min for this tool).

  **llm\_message:** I've used lookups too many times recently. I'll work with what I have.

  **Fix:** This is a soft limit, your call doesn't crash, the AI just stops calling the tool for a bit. If you legitimately need more, [open a ticket](mailto:hello@aisky.co.za) and we'll raise your quota.
</ResponseField>

## Each error code links to its docs

Every `error_code` in the dashboard's Invocations panel is a clickable link straight to the matching anchor on this page (e.g. `#http-tool-rate-limited`). So when you grep your invocation logs and see `HTTP_TOOL_TIMEOUT`, one click gets you to a fix.

<Card title="Next: Rate limits" href="/guides/http-tools/rate-limits">
  Token-bucket spec for the per-tenant and per-tool budgets.
</Card>
