Skip to content
docs
UseBuildChangelog
Open Lumin

Reference

Error codes

Lumin fails in two different shapes, and they are not interchangeable. A tool error happens inside an ordinary successful call. A pre-dispatch HTTP failure means the request never reached a tool at all.

Tool errors

When a tool cannot complete, for example the engine rejected the input, or a timeout, the call still succeeds at the JSON-RPC level. The response is HTTP 200, delivered like any other result over the SSE stream, with isError set on the tool result itself:

json
{
  "content": [{
    "type": "text",
    "text": "Engine returned 400: house_group must name at least one house"
  }],
  "isError": true
}

There is no structured error code here, no _meta block, and no recoverable flag. There is exactly one field to read: content[0].text, a plain-English message written for a model to act on directly. That text varies by tool and by what the engine or the network returned; it is not drawn from a fixed list.

Invalid or missing arguments are different again

A tool call whose arguments fail the tool's own schema (a missing required birth field, a value of the wrong type, a latitude out of range) is rejected before the tool handler ever runs. That comes back as a JSON-RPC protocol error, code -32602 ("Invalid params"), still on the same 200 SSE stream, not as an isError tool result. The server is stateless, so a missing birth field is nearly always this: an earlier set_birth_profile call does not supply data to the calls that follow it, every call carries its own birth fields.

Pre-dispatch HTTP failures

A smaller set of failures happen before any JSON-RPC message is parsed: authentication, the monthly allowance, and the transport's own header checks. Each of these is a real HTTP status other than 200, and each still carries a JSON-RPC error envelope in the body so a JSON-RPC client can parse it uniformly.

CodeHTTPCauseRecovery
-32001401No credentials, or the bearer token was rejected: missing, an unrecognized API key, an expired key, or an invalid/expired OAuth tokenRead the WWW-Authenticate header and let a compliant client start the OAuth flow, or generate a fresh API key at developer.lumin.guru
-32000429Both the monthly free allowance and the call pack balance are exhaustedRead error.data.packBalance and error.data.resetAt; buy a call pack or wait for the monthly reset, do not sleep-retry
-32000406Accept header on the POST is missing "application/json" or "text/event-stream" (both are required)Send Accept: application/json, text/event-stream on every request
-32000415Content-Type on the POST is not application/jsonSend Content-Type: application/json

401 carries WWW-Authenticate, which is what tells a compliant client to start the OAuth flow rather than just surface a failure. See auth for API key vs OAuth and rate limits for the full 429 body, including packBalance.

Idempotency

All Lumin tool calls are pure functions of their arguments, so retrying an isError result reproduces the same result. Only successfully executed calls are written to the usage log, so a failed call, whether a tool error or a pre-dispatch HTTP failure, never counts against the monthly allowance.