Skip to main content

Error taxonomy

Every Agent API error has the same shape:

{
"error": {
"code": "validation_failed",
"message": "handle is required.",
"suggested_action": "fetch_pipeline",
"suggested_endpoint": "GET /pipelines/{id}"
}
}
FieldDetail
error.codeAlways present. Stable identifier (closed list below).
error.messageAlways present. Human-readable; informational, not programmatic — code against code.
error.suggested_actionOptional. Agent-actionable next step when one is unambiguous (e.g. connect_account, fetch_artifact).
error.suggested_endpointOptional. The endpoint to call to take suggested_action.

X-Request-Id lives in the response header, not in the body. Correlate by that header when reporting issues.

Closed list of codes

HTTPcodeWhen
400bad_requestMalformed JSON, invalid cursor, missing required fields outside the validation set.
401unauthorizedAuthorization header missing, token wrong, or Whet Desktop has not minted an agent token yet (open the app once to provision).
403forbiddenToken is valid but the workspace state forbids the action (e.g. publishing while still in draft).
404not_foundResource doesn't exist in the workspace bound to this token.
409state_conflictResource isn't in a valid state for the operation (e.g. publish_artifact on a discarded artifact).
422validation_failedBody shape failed validation. message names the field.
424credential_missingAn adapter credential the operation needs is absent. suggested_action: connect_account with the relevant platform identifier.
424credential_deadThe stored credential exists but the probe failed (expired session, revoked token).
429rate_limitedPer-token quota exceeded. Retry-After carries the wait.
503backend_unavailableThe internal whet-app ↔ backend channel can't reach the backend. Check BACKEND_BASE_URL and that the backend container is healthy.
5xxinternal_errorUnhandled exception. Always carries X-Request-Id.

Suggested-action map

When an error is recoverable without a human in the loop, the response embeds a suggested_action. The agent can act on it directly:

suggested_actionMeaningRecommended call
connect_accountThe adapter has no usable session credential for this platform.POST /accounts/connect
fetch_artifactThe artifact may have changed state.GET /artifacts/{id}
fetch_pipelineThe pipeline may have changed state.GET /pipelines/{id}
diagnose_pipelineThe pipeline is unhealthy.GET /pipelines/{id}/diagnose

If you see a suggested_action not in this list, it's a forward-compatible value — log it and surface to the operator.

Rate limits

The Agent API rate-limits per token. Defaults:

  • Soft limit: 600 requests / minute per token.
  • Burst window: rolling 1 minute.

Headers emitted on every authenticated response (not just 429):

HeaderValue
RateLimit-Limit600
RateLimit-Remaininginteger
RateLimit-Resetseconds until reset

On 429:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
RateLimit-Limit: 600
RateLimit-Remaining: 0
RateLimit-Reset: 60
async function call(method: string, path: string, body?: object) {
const res = await fetch(`${WHET_BASE_URL}${path}`, {
method,
headers: {
"Authorization": `Bearer ${WHET_TOKEN}`,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
if (res.ok) return res.json();

const { error } = await res.json();
const requestId = res.headers.get("X-Request-Id");

switch (error.code) {
case "rate_limited": {
const retryAfter = Number(res.headers.get("Retry-After") ?? "5");
await sleep(retryAfter * 1000);
return call(method, path, body);
}
case "credential_dead":
case "credential_missing":
throw new CredentialError(error, requestId);
case "validation_failed":
throw new ValidationError(error, requestId);
case "unauthorized":
throw new AuthError(error, requestId);
default:
throw new ApiError(error, requestId);
}
}

Log correlation

Every response includes X-Request-Id. Copy that header when reporting an incident. The local Whet Desktop log file is indexed by the same id (default: ~/.whet/logs/whet.log on macOS/Linux, %LOCALAPPDATA%\Whet\logs\whet.log on Windows).

See also: Authentication, Idempotency, Webhooks.