Skip to Content
Errors

Errors

Every error the SDK produces extends InkletError, which preserves the backend’s own code, the HTTP status, a request ID, and any structured details.

class InkletError extends Error { readonly code: string; readonly status: number | undefined; readonly requestId: string | undefined; readonly details: Readonly<Record<string, unknown>> | undefined; toJSON(): Record<string, unknown>; }

toJSON() makes it safe to log the whole thing:

catch (error) { if (error instanceof InkletError) { logger.error({ err: error.toJSON() }, "inklet push failed"); } }

requestId can be handed to Inklet support without exposing anything secret. It is the fastest way to have a specific failure looked up.

Hierarchy

Error └── InkletError ├── ConfigurationError invalid_configuration ├── BrowserEnvironmentError browser_environment ├── AuthenticationError │ ├── AuthenticationFailedError authentication_failed │ ├── InvalidSecretKeyError invalid_secret_key │ └── RevokedSecretKeyError revoked_secret_key ├── PermissionDeniedError permission_denied ├── NotFoundError not_found ├── ConflictError conflict ├── PayloadTooLargeError payload_too_large ├── RateLimitError rate_limited ├── AssetUploadError asset_upload_failed ├── ApiError api_error ├── InvalidResponseError invalid_response └── NetworkError network_error

Thrown locally, before any request

ClassWhen
ConfigurationErrorBad options, bad asset, bad limit, bad idempotency key, a path that would leave the origin
BrowserEnvironmentErrorA document exists — this is not a trusted environment

These are programming errors. Retrying will not help.

Returned by the API

StatusClassTypical cause
401AuthenticationFailedErrorToken invalid or inactive
401RevokedSecretKeyErrorToken revoked
401InvalidSecretKeyError401 with no more specific code
403PermissionDeniedErrorValid token, wrong scope
404NotFoundErrorUnknown display, content, or presentation
409ConflictErrorIdempotency key reused with a different payload
413PayloadTooLargeErrorRequest body over the server limit
429RateLimitErrorRate limit exceeded
otherApiErrorAnything else non-2xx

Transport and parsing

ClassWhen
NetworkErrorThe service was unreachable, or the connection closed mid-response
InvalidResponseErrorA 2xx response the SDK could not parse or trust

InvalidResponseError is deliberately strict: the SDK validates the shape of every response and refuses to hand you a half-parsed object. If you see it consistently, the client and service versions are probably out of step.

AssetUploadError

Thrown when binary assets still could not be uploaded after the SDK refreshed their tickets and retried:

class AssetUploadError extends InkletError { readonly contentId: string | undefined; readonly failedAssetIndexes: readonly number[]; }
import { AssetUploadError } from "@inklethq/sdk"; try { await inklet.push.manual({ displayId, assets }); } catch (error) { if (error instanceof AssetUploadError) { for (const index of error.failedAssetIndexes) { console.error("failed to upload:", assets[index]); } } }

failedAssetIndexes maps back to the array you passed in.

A practical handler

import { AuthenticationError, ConfigurationError, InkletError, NetworkError, RateLimitError, } from "@inklethq/sdk"; async function push() { try { return await inklet.push.auto({ assets }); } catch (error) { if (error instanceof ConfigurationError) { throw error; // our bug — fail loudly, do not retry } if (error instanceof AuthenticationError) { await alertOperator("inklet token needs rotating"); throw error; } if (error instanceof RateLimitError || error instanceof NetworkError) { return scheduleRetry(); // transient } if (error instanceof InkletError) { logger.error({ err: error.toJSON() }); } throw error; } }

Credential redaction

Before an error reaches you, the SDK replaces any occurrence of your token in the message with [REDACTED]. Error messages are safe to log — but note this covers the message, not anything you attach yourself.

Last updated on