Skip to content

Troubleshooting the SDK

The errors the SDK, the Nuxt module and the CLI raise, what each one means, and the fix.

Updated 9 Sept 20264 min read
On this page

This page is for anyone staring at an error from @dukkan.one/app-sdk, @dukkan.one/nuxt or dukkan app. Every entry names the cause and the fix; where a portal page owns the fix, it is linked.

Errors the SDK throws#

Every error extends DukkanError and carries a stable code; API errors add status, requestId and details from the platform's error envelope.

Error Meaning Fix
DukkanAuthError with reason: "invalid_token" The access token was refused. The SDK already refreshed once and retried; this means the refresh failed too. Check DukkanReconnectRequiredError below; otherwise the clock of your server is off by more than the token lifetime allows.
DukkanAuthError with reason: "access_removed" The granting member lost access to the store. Send the merchant through consent again (Suspension).
DukkanAuthError with reason: "no_permissions" The install holds no effective scopes any more. Same: re-consent.
DukkanReconnectRequiredError The store has no tokens for the install, or a refresh answered invalid_grant and the row was marked. Show your "reconnect" screen; the merchant installs again. Never retry the refresh in a loop.
ScopeLostError 403: the call or the topic needs a scope the install does not hold. topics names the refused topics. Request the scope in dukkan.app.toml and re-consent, or drop the call.
DukkanRateLimitError 429 after the SDK's retry budget. retryAfterSeconds is the server's number. Slow down; the limits are in the API reference.
IdempotencyConflictError The same Idempotency-Key was sent with a different payload, or is still in progress (inProgress). Derive the key from the write's identity (idempotency: { ref }), never from the attempt.
InvalidTransitionError The order cannot move from its current status to the requested one. details.current_status says where it is. Read the status matrix; fetch the order and decide again.
DukkanWebhookError (constructEvent only) The delivery was refused: bad_signature, stale_timestamp, missing_headers, malformed_envelope, store_mismatch, body_too_large. See the receiver section below.
DukkanConfigError dukkan.app.toml failed validation; the message lists every problem. The dukkan.app.toml file.
DukkanNetworkError The platform could not be reached or timed out (15 seconds). Retry later; the SDK already retried idempotent calls.

The webhook receiver answers a refusal#

Body Status Cause Fix
bad_signature 401 The secret is wrong, or the body was re-serialised before verification. Load the secret the platform minted for this install; pass the raw request bytes.
stale_timestamp 400 The delivery is older than 5 minutes, or your clock is off. Sync the server clock; a genuinely late delivery is retried by the platform with a fresh signature.
missing_headers 400 No X-Dukkan-Timestamp or X-Dukkan-Hmac-Sha256. A proxy strips custom headers; forward them.
unknown_install 404 secretsFor returned null, or the signed install_id differs from the header hint. Persist the secret at install time (webhookSecrets.save); the platform retries until you do.
store_mismatch 403 The envelope's store_id is not the store you bound the install to. Never happens for a correctly stored install; investigate your binding.
body_too_large 413 Over 256 KB. The platform never sends that; check for a proxy that wraps bodies.
malformed_envelope 400 Verified bytes that are not a v1 envelope. Report it with the X-Request-Id; this is a platform bug.

A { "ok": true, "duplicate": true } answer means the inbox already held the event id: the platform retried a delivery you had acknowledged. Nothing to fix.

The Nuxt module#

Message Fix
Dukkan app is not configured: NUXT_DUKKAN_CLIENT_SECRET is not set (503, or a refused boot in production) Set the variable; the full list is in Environment.
sessionSecret must be at least 32 characters Generate one: openssl rand -base64 48.
dukkan.app.toml not found at build time Run dukkan app init, or point the module's configFile option at the file.
server/dukkan.ts not found Create it with defineDukkanApp; see Your side of the contract.
oauth_state_mismatch on the callback The state cookie expired (10 minutes), the callback arrived on a different host than the install request, or cookies are blocked. Check NUXT_DUKKAN_APP_BASE_URL matches the host merchants use.
store_not_allowed on the callback A public tunnel is up and NUXT_DUKKAN_ALLOWED_STORE_IDS restricts installs to your sandbox. Expected while developing.
token_exchange_failed:invalid_grant The code was used twice or the redirect URI differs from the registered one byte for byte.

The CLI#

Message Fix
✗ Not signed in. Run: dukkan login Sign in; credentials are bound to one sandbox store.
✗ The app is not running on port 3000 with dev routes Start it with dukkan app dev; rehearsals need the dev routes, which exist only in nuxt dev.
✗ The portal draft changed since your last pull Pull, or push with --force; see Drift.
✗ This draft is under marketplace review and frozen Withdraw the submission in the portal first.
✗ clients:read needs the accepted data processing agreement Accept it on the portal's Account page (Scopes).
✗ The platform refused the rehearsal Sandbox stores only; the subscription must include the topic; the sandbox needs seeded data (Sandbox stores).
cloudflared not found Install it, or pass --tunnel-url with any HTTPS tunnel, or run --no-tunnel and use webhook trigger --local.

Every CLI command accepts --json for one JSON object per line when you need to script around it. The full command list is in the CLI reference.

Next steps#