Errors
The SDK raises two error types, and which one you caught tells you where the problem is before you read the message.
ts
import { EvalwrightApiError, EvalwrightClientError } from "@evalwright/sdk";
try {
await client.prompts.resolve("support-reply", { vars });
} catch (err) {
if (err instanceof EvalwrightApiError) {
// The server answered, and the answer was a refusal.
console.error(err.status, err.code, err.message, err.details);
} else if (err instanceof EvalwrightClientError) {
// The call never left your process: the client was constructed wrong.
} else {
// Network, DNS, timeout, abort — the platform's own errors, unwrapped.
}
}EvalwrightApiError
| Property | Type | Description |
|---|---|---|
status | number | HTTP status. |
code | string | Stable machine-readable code — branch on this, not on the message. |
message | string | Human-readable explanation. |
details | unknown | Present when the server can say more, e.g. which variable was missing. |
| Status | Code | What it means |
|---|---|---|
400 | VALIDATION_ERROR | A required {{variable}} was not supplied. |
401 | UNAUTHORIZED | The key is missing, malformed, revoked — or not scoped to this prompt. |
404 | NOT_FOUND | No such prompt, or it has no production version and you did not pin one. |
401 deliberately does not distinguish "revoked" from "out of scope": telling a caller which of the two it was tells them something about keys they do not hold.
EvalwrightClientError
Raised locally, before any request: a missing apiKey or a missing baseUrl. It means the client was built wrong, so retrying will not help — fix the construction.
Retrying
429 and 5xx arrive as EvalwrightApiError. Retry those with backoff. Do not retry 400, 401 or 404: the same request will be refused the same way, and a retry loop against 401 is how a key gets rate limited.