Cassette

Error codes and fixes

HTTP API errors: non-2xx with {"error":{"code","message","fix?"}}. Contract calls revert with a named error; the relay (POST /v1/relay) refuses a call that would revert with relay_reverted and the name in message, and the paywall and the sign page decode them the same way. Apply the fix and retry once; never retry in a loop.

HTTP API (code uses underscores)

codestatusmeaning / fix
bad_request, bad_json, bad_address, bad_amount, bad_message400malformed input; fix the body/query
bad_domain, bad_nonce, bad_signature, expired, wrong_chain400/401SIWE login problems: request a fresh nonce and sign the new message
unauthorized, bad_token401missing/expired bearer token: log in again
forbidden, no_access, no_license, not_operator, no_profile403/409caller lacks rights: use the studio owner/operator key
read_the_storefront409licence attestation asked for a storefront game: read the developer's storefront on chain instead (https://cassette.gg/agents/verify-ownership.md)
refunded403legacy Checkout games only (Cassette's own refund record). Storefront refunds burn the tokens instead
hosting_off / hosting_first_party_only410/403Cassette doesn't host builds: host in your own account (https://cassette.gg/agents/host-game.md), then register the pointer (https://cassette.gg/agents/publish-game.md)
personal_data_in_reason422a public takedown reason contains an email, phone number, @username or wallet address: describe the broken rule instead
target_not_allowed, function_not_allowed, value_not_allowed, gas_too_high, deadline_too_far, bad_request_signature400/403relay policy: only platform contracts or factory storefronts, no token transfers or approvals, value 0, gas ≤ 1.5 M, deadline ≤ 24 h
relay_reverted422the call would revert; message names the reason
relay_unavailable503relayer, or the storefront router, not deployed: retry later
not_found, not_ready, not_playable, delisted404unknown / still indexing (retry in seconds) / not playable
already_claimed, already_released409community listing state
invalid_manifest, missing_manifest, bad_zip, unsafe_path, too_many_files, too_large, data_too_large413/422legacy build upload problems
rate_limited429wait and retry (relay: 20 tx/min and 500/day per wallet)
faucet_unavailable, not_deployed503platform not fully up: retry later

Contract reverts (storefront, factory, router)

Decode a revert's first 4 bytes with cast 4byte-decode <data> or your library's ABI decoder (https://cassette.gg/agents/paywall.md lists the storefront's errors).

errormeaningfix
NotStorefrontThat address is not a storefront created by the Cassette storefront factory.Check the storefront address in cassette.json (factory.isStorefront must be true).
ERC2771UntrustfulTargetThat address is not a storefront created by the Cassette storefront factory.Check the storefront address in cassette.json (factory.isStorefront must be true).
NotOwnerOnly the storefront's owner can do that.The human (the owner wallet) signs it: send them a sign link (protocol.md §6).
NotOperatorThis key can't manage the storefront's listings.Send the human a set-operator sign link for this key, or put the call itself in a sign link (protocol.md §6).
ListingInactiveIt is not on sale right now.Turn it back on with updateListing(…, active true, …) (https://cassette.gg/agents/sell-items.md).
NoSuchListingThat item or licence is not listed.Create the listing (createListing, https://cassette.gg/agents/sell-items.md).
AlreadyLicensedThis wallet already owns the game.Nothing to buy: refresh ownership.
FreeClaimUsedThis wallet already claimed it.Nothing to claim: refresh ownership.
PriceOverMaxThe price went up since it was shown. Nothing was charged.Show the new price and ask again.
PermitAmountMismatchThe payment authorisation didn't match the price. Nothing was charged.Sign a permit for exactly the total (quote).
BadQuantityThat quantity is not allowed.Licences and free listings are 1 per wallet; quantities must be at least 1.
SelfRefundUnavailableThis purchase can't be refunded from here.Check canSelfRefund(saleId) for the reason (window closed, gift, cap, seller decision, registry); the seller can always refund.
NotReleasableThat sale is still inside its refund window, or already paid out.Release after the window ends (release([saleId]), https://cassette.gg/agents/handle-refunds.md).
AlreadyRefundedThat sale was already refunded.Nothing to do.
BadRefundPolicyRefund window over 14 days, or a registry other than Cassette’s.Use a window of 0–336 hours and the factory abuse registry or none.
BadReferralReferral fee over 30%, or a fee without a partner.Keep the referral as the factory proposes it.
BadTextA name or URL is too long or has characters a storefront rejects.URLs: visible ASCII, at most 512 bytes.
BadListingThe listing is out of bounds (price, supply, or a consumable licence).Prices < 2^128, supply ≤ 2^53−1, only items may be consumable.
TermsChangedThe seller changed the terms, the seller details or the refund rules since they were shown. Nothing was charged.Show the current terms again (refresh) and ask again.
NoSellerRecordThe storefront needs its seller record (URI and hash) first.Publish the seller record: setSellerRecord(uri, hash) (https://cassette.gg/agents/set-up-seller.md).
ERC2771ForwarderExpiredRequestThe signed request expired before it was sent.Re-run the command (it signs a fresh request).
ERC2771ForwarderInvalidSignerThe signed request doesn't match its sender.Re-run the command with the same key.
InvalidAccountNonceThe signed request was already used or out of order.Re-run the command (it reads the current nonce).
SupplyExhaustedSold out.List a new item (supply is fixed per listing).
TokensGoneWhat was bought was transferred or used, so it cannot be returned.The seller can still refund it.
SkuInUseThat sku is already listed in this storefront.Update the existing listing (updateListing) or pick another sku.

Paywall and play-frame results

StorefrontTxResult.reason and TopUpResult.reason from the play-frame bridge (https://cassette.gg/agents/paywall.md): cancelled (the player closed the wallet; nothing charged), signed-out, wrong-chain, not-a-storefront (the address isn't a factory storefront: payment stopped), unsupported (this host can't do it: gifts, or a top-up where none is offered), insufficient-funds (say how much USDC to add; the host's top-up when it offers one), failed (with error.name when the chain refused).

Hosting

Hosting tool failures (login, limits, names taken), Arweave funding (host-fund, once Arweave opens) and games a host can't serve (arweave-unsuitable): https://cassette.gg/agents/host-game.md.