SDK
Error handling
Every SDK error is a LeashError with a machine-readable code, a human message, and (often) an action hint plus a seeAlso doc link.
Error codes
| Code | Meaning | Fix |
|---|---|---|
NO_API_KEY | LEASH_API_KEY is missing in server mode. | Set LEASH_API_KEY in the env where the SDK runs. |
NO_REQUEST_SERVER_CONSTRUCT | Leash was constructed in a server environment without a request object. | Pass { request: req } to the Leash constructor inside an API route or server handler. |
BROWSER_MODE_UNSUPPORTED | Leash was constructed (or a server-only method was called) from the browser. Not supported in 0.4-alpha. | Move the call to an API route and construct Leash with { request: req } there. |
UNAUTHORIZED | The leash-auth cookie is missing, invalid, or expired (platform returned 401). | Ensure the calling user has a valid session, or use leash dev to mint a local cookie. |
INTEGRATION_NOT_ENABLED | The provider is not connected for this user, or the app is not on the allow-list (platform returned 403). | Connect the provider at /dashboard/integrations and confirm the app is allow-listed. |
INTEGRATION_ERROR | The upstream provider returned an error. Includes the upstream message. | Inspect err.message — most are caller bugs (bad params, missing scopes) or transient upstream issues. |
UPGRADE_REQUIRED | The call requires a higher plan (platform returned 402). | Upgrade at /dashboard/billing. |
NETWORK_ERROR | The SDK could not reach the Leash platform at all. | Check connectivity and that LEASH_PLATFORM_URL (if set) points somewhere reachable. |
Source of truth: LeashErrorCode in @leash/sdk/leash.
Handle it
app/api/inbox/route.ts
import { Leash, LeashError } from '@leash/sdk/leash'export async function GET(req: Request) {const leash = new Leash({ request: req })try {const messages = await leash.integrations.gmail.listMessages({ maxResults: 5 })return Response.json({ messages })} catch (err) {if (err instanceof LeashError) {switch (err.code) {case 'UNAUTHORIZED':return Response.json({ error: 'sign in' }, { status: 401 })case 'INTEGRATION_NOT_ENABLED':return Response.json({ error: 'connect gmail', connect: '/dashboard/integrations' }, { status: 403 })case 'UPGRADE_REQUIRED':return Response.json({ error: err.message, upgrade: '/dashboard/billing' }, { status: 402 })default:console.error(err.code, err.toString())return Response.json({ error: err.message }, { status: 500 })}}throw err}}
LeashError shape
class LeashError extends Error {readonly code: LeashErrorCodereadonly action?: string // human-readable fix hintreadonly seeAlso?: string // doc URLtoString(): string // pretty: "× message\n Fix: action\n See: seeAlso"}
Log err.toString() in dev — it surfaces the action and link directly. In prod, branch on err.code.
See also: SDK overview for the full surface.