Skip to content

Error handling

Catch inference failures at ask inside .tsi, or at the await when calling an infer function from plain TypeScript. Nola uses the error classes below for its own failures. Errors thrown by your application code can also propagate through the call.

These classes are exported from @nola-lang/runtime, except NolaSchemaError, which comes from @nola-lang/core.

Class When Carries
NolaResolutionError an ask could not produce a valid value — after the correction retry, on a value that fails the type contract, or when a call intent’s callee is not a function details.site, details.prompt, details.raw, trace
NolaProviderError the provider call failed (HTTP error, network, malformed reply) — and a replay miss (NOLA3008, definitive) status?, definitive?, retryAfterMs?, code?, details?
NolaConfigError the config is invalid, names an unknown model, or is frozen code? (NOLA3003–NOLA3007, NOLA3012)
NolaIntentError an intent was used outside ask or in a browser, or a decision type was sent to a model without decision support code (NOLA3010, NOLA3013, NOLA3018) — definitive
NolaSchemaError (from @nola-lang/core) an underivable type reached an ask code (NOLA3009) — definitive
NolaValidationError a type value’s parse method rejected its input code (NOLA3016), issues
NolaVersionError emit-contract mismatch or two runtimes loaded code (NOLA3001, NOLA3002), details

Nola parses the model’s reply and validates it against the extractor’s schema. If it fails, the runtime makes one correction attempt, sending the reply and validation error back to the provider. The hooks report onValidationFailed followed by onRetry; the receipt records two attempts and the revised effectivePrompt. If the second reply is also invalid, the ask throws a NolaResolutionError:

Intent resolution failed after retry at src/person.tsi:10:18 — …

A fixed label set gives the correction request a specific constraint to report, such as “one of billing, refund, fraud, other”.

Wrap the awaited infer function in try/catch and handle the errors your application can recover from:

src/person.tsi
export interface Person { name: string; age: number }
export infer function extractPerson(.message: string) {
return ask `the person described in the text`: Person;
}
src/main.ts
import { NolaProviderError, NolaResolutionError } from "@nola-lang/runtime";
import { extractPerson } from "./person.tsi";
try {
const person = await extractPerson("Alice Smith, 32, works at Acme Corp.");
console.log(person);
} catch (error) {
if (error instanceof NolaResolutionError) {
// where: the .tsi position of the ask; what: the last raw model text
console.error(`ask at ${error.details.site} failed: ${error.message}`);
console.error("last reply:", error.details.raw);
} else if (error instanceof NolaProviderError) {
console.error(`provider failure${error.status ? ` (HTTP ${error.status})` : ""}:`, error.message);
} else {
throw error;
}
}

details.site identifies the ask’s original .tsi location as file:line:col. details.prompt contains the last composed prompt, and details.raw contains the last reply. When present, trace records the asks and nested invocations that ran.

A NolaProviderError is definitive if its flag says so, or if its HTTP status is 4xx other than 408 or 429. Examples include authentication failures, invalid requests and unknown models. The provider-level withRetry helper stops on these errors. Other errors follow the retry policy, with the provider’s retryAfterMs extending the delay when needed.

NolaIntentError and NolaSchemaError are also definitive because they require a change to the code or configuration. See NOLA3010 and NOLA3009.

For model: "nola", branch on the server’s code field:

Code HTTP status Meaning
quota_exceeded 402 The trial runs are used. details.runsUsed and details.runsLimit report usage.
insufficient_credits 402 The account balance is empty.
unauthorized 401 The key is invalid.
rate_limited 429 The account is rate-limited. retryAfterMs gives the wait time.
request_too_large 413 The ask exceeds the request-size limit.

The quota and balance errors direct you to nola account or to configure your own provider. Error messages can change, so use the code for application logic.

Choose the retry layer that matches the failure. The automatic correction attempt handles invalid answers. withRetry(model, policy) in the config handles provider failures. .withRetry(n) on an intent repeats the intent, including a call intent’s function, so repeated side effects must be safe. See Resilience for the full comparison.

ask.timeoutMs defaults to 60 000 ms and supplies the invocation’s timeout. .withTimeout(ms) can set a timeout on an intent; an individual ask remains subject to the enclosing invocation’s deadline.

When a deadline expires, the abort signal cancels pending provider work and the await rejects with a timeout error. It does not cancel a call intent’s function once that function has started. See Ask options.

NolaConfigError can occur while loading the config or resolving a model name at ask time. Its message identifies the problem; Config schema lists the codes.

NolaVersionError means the compiled code expects a different runtime contract (NOLA3001) or incompatible runtime copies are loaded (NOLA3002). Keep Nola packages on matching versions, rebuild the application and use npm dedupe if duplicate dependencies remain.

Next: Deploying