Error codes.

Every error of subkit and shopkit has a code and links here – as docsUrl of the thrown error and in the docs field of HTTP responses. Find the code, read the cause, apply the fix.

Coding agents: the docs MCP server at https://agentkit.ch/mcp explains a code with explain_error.

subkit

Subscriptions, invoices and the self-service API.

CUSTOMER_NOT_FOUNDHTTP 404

Cause: No billing customer with this externalId – it is created on the first subscription or with upsertCustomer().

Fix: Call upsertCustomer({ externalId, email, name }) first, or check the id.

PLAN_NOT_FOUNDHTTP 404

Cause: The planId is not among the plans passed to subkit().

Fix: Use an id from the configured plans (the MCP tool list_plans lists them).

PLAN_NOT_PURCHASABLEHTTP 400

Cause: The plan has no price for this interval, or it is hidden (no longer sold).

Fix: Offer only the intervals in plan.prices. A hidden plan stays with its subscribers but cannot be bought.

SUBSCRIPTION_EXISTSHTTP 400

Cause: The customer already has a running subscription.

Fix: Change the plan with changePlan() instead of subscribe().

NO_SUBSCRIPTIONHTTP 400

Cause: The action needs a running subscription, and the customer has none (never subscribed, or it ended).

Fix: Start one with subscribe(). getOverview() shows the current state.

INVALID_STATEHTTP 400

Cause: Not possible in the current state: the checkout of the subscription is unfinished, or an open invoice has to be settled before a plan change.

Fix: Finish or cancel the checkout, or pay the open invoice, then try again.

PAYMENT_METHOD_REQUIREDHTTP 400

Cause: An upgrade is charged right away and needs a saved card or TWINT – there is none.

Fix: Let the customer add one (POST …/payment-method) or switch to invoice.

PAYMENT_FAILEDHTTP 400

Cause: The charge of an upgrade was declined (card declined, not enough funds, TWINT refused). The plan stays as it was.

Fix: Ask the customer to update the payment method, then try again.

PROVIDER_UNAVAILABLEHTTP 503

Cause: The payment provider could not be reached or answered with an error (this is not a declined card).

Fix: Try again later. Check the provider’s status and the API key (zahls.ch: instance and key).

INVOICE_NOT_FOUNDHTTP 404

Cause: No invoice with this id for this customer – or, when paying, no open one.

Fix: Check the id and that the invoice belongs to the signed-in customer.

OVERDUE_INVOICEHTTP 402

Cause: An invoice of the customer is overdue or written off; nothing new is sold until it is paid.

Fix: Pay it first (POST …/invoices/:id/pay or by QR-bill), then try again.

COLLECTION_METHOD_UNAVAILABLEHTTP 400

Cause: This payment option (card / TWINT or invoice) is not enabled in collectionMethods of the handler.

Fix: Add it to collectionMethods, or offer only the enabled options.

BUSYHTTP 409

Cause: Another request is changing the same subscription, order, cart or stock at this moment (e.g. a renewal or a webhook).

Fix: Try again in a moment – nothing is lost.

RATE_LIMITEDHTTP 429

Cause: Your rateLimit callback refused the request, or too many webhooks arrived for one payment.

Fix: Wait the seconds in Retry-After. If real customers hit the limit, raise it.

WEBHOOK_INVALIDHTTP 400

Cause: A webhook could not be verified: unknown transaction, amount or currency differ, or the body is not JSON.

Fix: Point the provider’s webhook (format JSON) to …/webhook and use the same instance and API key as the kit. Forged requests end here on purpose.

UNAUTHORIZEDHTTP 401

Cause: The authorize (or identify) callback of the handler did not accept the request – no session, or no access.

Fix: Send the session cookie or token with the request and check the callback.

UNSUPPORTED_MEDIA_TYPEHTTP 415

Cause: A POST without Content-Type: application/json. The handlers require it as CSRF protection.

Fix: Send JSON with exactly this content type – the React clients of the kits already do.

INVALID_JSONHTTP 400

Cause: The request body is not valid JSON.

Fix: Send a JSON object as the body.

INVALID_INPUTHTTP 400

Cause: A field is missing, has the wrong type or is out of range (e.g. an unknown interval, a negative amount, a link that is not http(s)).

Fix: Check the field the message names against the README of the kit.

NOT_FOUNDHTTP 404

Cause: No route for this method and path below the basePath of the handler.

Fix: Check that basePath matches where the route is mounted, and the HTTP method.

INTERNAL_ERRORHTTP 500

Cause: An unexpected error (database, bug). The details are not sent to the client.

Fix: Look at onError and the server log. A bug in a kit: report it with the stack trace.

shopkit

Catalog, cart, checkout, orders and the back office API.

PRODUCT_NOT_FOUNDHTTP 404

Cause: No product with this id or slug.

Fix: Check id or slug. Archived products are only in the back office.

VARIANT_NOT_FOUNDHTTP 404

Cause: No variant with this id.

Fix: Use an id from product.variants.

NOT_FOR_SALEHTTP 400

Cause: The product or variant is a draft or archived.

Fix: Activate it in the back office, or remove it from the cart.

OUT_OF_STOCKHTTP 409

Cause: Fewer items in stock than asked for (stock is reserved at checkout).

Fix: Lower the quantity – the message says how many are left.

INVALID_QUANTITYHTTP 400

Cause: A quantity below 1 or above the maximum per line, or too many items in the cart.

Fix: Use a whole number within the limit the message names.

CART_NOT_FOUNDHTTP 404

Cause: No cart with this token (a wrong token, or an old cart that was abandoned).

Fix: Create a new cart – the React provider does this by itself.

CART_EMPTYHTTP 400

Cause: Checkout of a cart without items.

Fix: Add items first.

CART_CLOSEDHTTP 409

Cause: The cart was already turned into an order.

Fix: Show the order, or start a new cart.

DISCOUNT_INVALIDHTTP 400

Cause: Unknown, expired, inactive or used-up discount code.

Fix: Check the code in the back office (list_discounts).

DISCOUNT_NOT_APPLICABLEHTTP 400

Cause: The code is valid, but this cart does not qualify (minimum order value, products).

Fix: Meet the conditions, or remove the code.

GIFT_CARD_INVALIDHTTP 400 · 404

Cause: Unknown, disabled or expired gift card, or its balance is too low.

Fix: Check the code (dashes and case do not matter) and the balance.

EMAIL_REQUIREDHTTP 400

Cause: Checkout without an email address.

Fix: Set email in the cart details (updateCartDetails()).

ADDRESS_REQUIREDHTTP 400

Cause: Physical items need a shipping address.

Fix: Set shippingAddress in the cart details.

SHIPPING_RATE_REQUIREDHTTP 400

Cause: Physical items, but no shipping method chosen.

Fix: Set shippingRateId to one of the offered rates.

SHIPPING_RATE_UNAVAILABLEHTTP 400

Cause: The chosen shipping method does not exist or does not fit this cart.

Fix: Pick one of the shippingOptions of the cart.

FULFILLMENT_DATE_REQUIREDHTTP 400

Cause: The chosen shipping rate has a schedule, but the cart has no pickup or delivery day yet – or no time window although there are some.

Fix: Set a day from shippingOptions[].schedule.dates (and a window from timeWindows) with updateCartDetails({ fulfillmentDate, fulfillmentWindow }).

FULFILLMENT_DATE_UNAVAILABLEHTTP 400

Cause: The day or time window is not (or no longer) offered: before the lead time, after the cutoff, on a closed day or beyond maxDays.

Fix: Choose a day from the current schedule.dates of the shipping rate – the list changes over time and with the products in the cart.

PAYMENT_METHOD_UNAVAILABLEHTTP 400

Cause: The payment method (online or invoice) is not offered for this shop or order, or no provider is configured.

Fix: Configure the provider and the methods in createShop(), or choose another method.

PAYMENT_METHOD_NOT_FOUNDHTTP 404

Cause: The customer has no (such) saved payment method: none saved yet, removed, refused by the provider and deactivated, or it belongs to another customer.

Fix: Order without useSavedPaymentMethod (payment link) and let the customer save one with savePaymentMethod: true.

AMOUNT_CHANGEDHTTP 409

Cause: The amount due differs from the one the customer confirmed (expectedAmount), e.g. because a price, discount or shipping changed. Nothing was charged.

Fix: Quote the order again (quoteOrder / quote_order), show the customer the new amount and order again with the confirmed amount.

ORDER_NOT_FOUNDHTTP 404

Cause: No order with this id, or the token of the order link does not match.

Fix: Check the id and the token of the order link.

INVALID_STATEHTTP 409

Cause: Not possible in the state of the order: paid already, cannot be paid, not paid yet (refund), canceled.

Fix: Read status, paymentStatus and fulfillmentStatus of the order first.

REFUND_TOO_HIGHHTTP 400

Cause: The refund is more than what is left to refund, or the gift cards of the order were used already.

Fix: Refund at most the amount in the message.

DUPLICATEHTTP 409

Cause: A product slug, SKU or discount code with this value exists already.

Fix: Choose another one, or change the existing record.

PROVIDER_UNAVAILABLEHTTP 503

Cause: The payment provider could not be reached or answered with an error (this is not a declined card).

Fix: Try again later. Check the provider’s status and the API key (zahls.ch: instance and key).

BUSYHTTP 409

Cause: Another request is changing the same subscription, order, cart or stock at this moment (e.g. a renewal or a webhook).

Fix: Try again in a moment – nothing is lost.

RATE_LIMITEDHTTP 429

Cause: Your rateLimit callback refused the request, or too many webhooks arrived for one payment.

Fix: Wait the seconds in Retry-After. If real customers hit the limit, raise it.

WEBHOOK_INVALIDHTTP 400

Cause: A webhook could not be verified: unknown transaction, amount or currency differ, or the body is not JSON.

Fix: Point the provider’s webhook (format JSON) to …/webhook and use the same instance and API key as the kit. Forged requests end here on purpose.

NO_PAYMENT_SLIPHTTP 400

Cause: A bank import, but the back office handler has no payment slip to compute the references.

Fix: Pass receipts.paymentSlip (e.g. swissQrBill()) to createShopAdminHandler().

INVALID_CAMTHTTP 400

Cause: The bank file is not a camt.053 or camt.054 XML document.

Fix: Export camt.054 (or camt.053) as XML from e-banking and send it as { "camt": "<?xml …" }.

HSSOFT_REJECTEDHTTP 502

Cause: HS-Soft (WaWiAssist) refused the request: invalid API key, a channel the key may not write, a locked order date, an order that is already invoiced or an unknown article. error.details.type names the reason.

Fix: Fix the cause (check the API key with HS-Soft, correct the date or article) and send the order again with syncOrder(id, { force: true }). Retrying unchanged will not help.

HSSOFT_UNAVAILABLEHTTP 503

Cause: HS-Soft could not be reached or failed temporarily (503, timeout, gateway error).

Fix: syncOrders() tries again by itself after retryMinutes. If the order is uncertain, first check in WaWiAssist whether it arrived – only then send it again.

HSSOFT_UNMAPPEDHTTP 422

Cause: An order line or the shipping costs have no HS-Soft article – the product does not come from the import.

Fix: Import the product from HS-Soft, set orders.articleId or orders.shippingArticleId, or leave the order out with orders.filter.

SWISSPOST_REJECTEDHTTP 502

Cause: Swiss Post refused the request: client or scopes of the Digital Commerce API, the franking licence, a combination of services the item cannot have, an address Swiss Post cannot deliver to – or an item abroad (labels are for Switzerland and Liechtenstein). error.details.errors lists the Swiss Post codes (E2001 …).

Fix: Fix the cause (check client and scopes with Swiss Post, the licence, the services of the shipping rate or the address) and create the label again. Retrying unchanged will not help.

SWISSPOST_UNAVAILABLEHTTP 503

Cause: Swiss Post could not be reached or failed temporarily (timeout, 5xx, E9999).

Fix: Create the label again later. Address suggestions and the address check at checkout do not fail because of it – the order goes on without them.

UNAUTHORIZEDHTTP 401

Cause: The authorize (or identify) callback of the handler did not accept the request – no session, or no access.

Fix: Send the session cookie or token with the request and check the callback.

UNSUPPORTED_MEDIA_TYPEHTTP 415

Cause: A POST without Content-Type: application/json. The handlers require it as CSRF protection.

Fix: Send JSON with exactly this content type – the React clients of the kits already do.

INVALID_JSONHTTP 400

Cause: The request body is not valid JSON.

Fix: Send a JSON object as the body.

INVALID_INPUTHTTP 400

Cause: A field is missing, has the wrong type or is out of range (e.g. an unknown interval, a negative amount, a link that is not http(s)).

Fix: Check the field the message names against the README of the kit.

NOT_FOUNDHTTP 404

Cause: No route for this method and path below the basePath of the handler.

Fix: Check that basePath matches where the route is mounted, and the HTTP method.

METHOD_NOT_ALLOWEDHTTP 405

Cause: The back office API accepts only GET and POST.

Fix: Use POST for changes.

TOO_LARGEHTTP 413

Cause: The request body is too large (100 kB; bank files 20 MB).

Fix: Send less – split a large bank file, for example.

INTERNAL_ERRORHTTP 500

Cause: An unexpected error (database, bug). The details are not sent to the client.

Fix: Look at onError and the server log. A bug in a kit: report it with the stack trace.

← agentkit home