inklet docs

Errors

The inklet SDK error hierarchy — every class, its code, and what to do when you catch it.

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
    │   └── SubscriptionRequiredError   subscription_required
    ├── 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
403SubscriptionRequiredErrorValid token, but the requested AI feature requires Pro
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,
  SubscriptionRequiredError,
} 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 SubscriptionRequiredError) {
      await alertOperator("upgrade or manage the inklet subscription");
      throw error; // not transient; keep the same PAT after the plan changes
    }

    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.

On this page