Errors
When the gateway turns your request down, you get JSON back. It always carries prose for whoever is
reading it. Where the next action depends on which rule was broken, it carries a reason a client
can branch on too.
{
"status": "error",
"error": "This deploy credential does not carry the 'write:functions' capability, which this route requires.",
"reason": "credential-missing-capability",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
The gateway writes error for a person, and its wording can change. Key off reason instead. The
codes are a fixed list, generated from the gateway’s own enum. Adding one is a deliberate change to
this API.
Not every refusal carries a reason. You get one where two refusals share a status code and mean
different things. taken and locked both answer 409. One says pick another name. The other says
the workspace renamed less than 30 days ago, and carries renamable_at, the moment it can rename
again.
The trace ID
Section titled “The trace ID”Every refusal carries a trace_id. It names this one request, and nothing else. Every answer from
the management API carries the same ID in the x-wawesome-trace-id header, including the ones
that worked. A browser on another origin can read that header too.
If you write to us about a refusal, paste the trace ID. We search our logs by it, so it takes us straight to your request. We keep those logs for 35 days. After that, the ID finds nothing.
If your client sends a valid W3C traceparent header, we use its trace ID rather than making a new
one, so you can match our answer to your own traces. If the header is missing or malformed, we make
a new ID and answer the request as usual.
This is only for the management API, which the CLI, the dashboard and MCP talk to. An answer from
your Function carries x-wawesome-invocation-id instead.
Where you meet one
Section titled “Where you meet one”npx wawesome prints the gateway’s prose rather than a message of its own. What you read in the
terminal is what came back on the wire. Where the fix is the billing page, it adds the link:
[wawesome] Error: This plan grants 3 App slots, and 3 are occupied. Delete an App to free one, or move to a plan with more.
Trace ID: 4bf92f3577b34da6a3ce929d0e0e4736
[wawesome] Where to resolve it: https://dashboard.wawesome.io/billing
The trace ID is on its own line, so a pasted terminal block is enough for us to find the request. The dashboard shows the trace ID under every refusal, with a button to copy it. That holds for a page that stops on one and for a message inside a panel or a dialog.
An MCP tool returns the same object in its result, trace_id included. An agent reading reason knows
whether to ask for a wider credential or to stop asking.
Two refusals also carry numbers. app-slots-exhausted and storage-exhausted add an allowance
object with granted and occupied, so a client can say 3 of 3 without parsing the sentence.
Slots on the first, bytes on the second.
Every reason
Section titled “Every reason”The list below is generated from RejectionReason in the gateway. A reason with nothing written for
it yet still appears here, under its code.
takenSomeone else already holds the name.
Send a different one.
reservedThe platform keeps this name for itself.
Send a different one. Waiting does not free it.
malformedThe value breaks the rules for its kind. A workspace address becomes part of a hostname, so it is lowercase letters, numbers and single hyphens and nothing else. A
--dns-providerthe platform holds no guidance for lands here too, and that refusal lists the ones it does hold.Fix the value and send it again. An App name or a Function name never reaches this, because the platform cleans those up rather than refusing them.
too-shortThe name obeys the rules for its kind. It is still shorter than the address it becomes allows.
Use at least three characters.
lockedWhat allowed this change is no longer true. A workspace address locks the first time you promote a version, because live URLs carry it from then on.
There is nothing to retry. The name stays as it is.
app-slots-exhaustedEvery App slot the plan grants is occupied.
Delete an App you are done with, or move up a plan. The refusal carries an
allowanceobject withgrantedandoccupied, so you can print3 of 3without reading the sentence.storage-exhaustedThe files this deploy would store take the workspace past what its plan holds. Deploys only. Nothing already serving is dropped.
Ship fewer files, or move up a plan. The
allowanceon the refusal is in bytes.seats-exhaustedThe workspace already holds as many people as its plan does, counting everybody here and every invitation nobody has answered yet. A free workspace holds one person, so it cannot invite anybody at all.
Take an invitation back, or move up a plan. The refusal carries an
allowanceobject withgrantedandoccupied. It can also arrive when somebody accepts a link, if the plan moved while it was out there.tenant-restrictedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.payment-requiredThe workspace owes money, and this is one of the few actions that stops until it does not. Everything already deployed goes on serving.
Settle up on the billing page. The CLI prints the link under the refusal.
paid-plan-requiredThe plan does not grant what the request asked for. A Schedule is the usual one. The paid plan has them, the free plan does not.
Move up a plan. Freeing something up changes nothing, because nothing here is occupied.
custom-domain-attachedThe App already answers at a custom domain, and an App carries one.
Detach the one that is there, then attach the new name. Detaching takes the site on the old name dark, so do it when you mean to.
custom-domain-detachingThe domain has stopped answering and the certificate vendor has not let the name go yet, so the App still holds its one domain place.
Detaching again finishes it now. Left alone, the platform finishes it on its own.
custom-domain-verifiedControl of the domain has been proved, so the claim is an address callers reach. Nothing was cancelled, and the App answers at every name it did.
Take it off at the dashboard, with the hostname typed. The route is open to
write:domains, so this is the claim refusing rather than the credential.assets-reclaimedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.publish-needs-confirmationNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.asset-drop-needs-confirmationNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.already-liveThe deploy is byte for byte the version that is live now. We made no new version, because nothing changed.
Nothing.
wawesome deployprints a line and exits 0, so a CI job that deploys on every push stays green.already-a-versionThe deploy is byte for byte a version the Function already has, and that version is not live. Versions never change, so we made no new one.
Run
wawesome version switch <version>with the number the refusal names.wawesome deployexits 1 here, so CI does not pass while other code is serving.schedule-undeclaredThe Schedule is no longer in
wawesome-function.json, so there is nothing left to resume.Put the cron back in the config file and deploy. Nothing runs in production that is not in your repository.
schedule-suspendedThe platform has suspended the Schedule. The workspace owes payment, its subscription ended, or it has spent far past what its plan allows. Which of those it was is not recorded.
Settle up, subscribe again, or move up a plan. The start of the next usage period ends it too, and the job starts again on its own with no redeploy. Until then neither
cron pausenorcron resumereaches it.signups-closedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.terms-not-acceptedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.deploy-raced-reclamationNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.Not written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.Not written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.invalid-base-tokenNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.invalid-tenant-tokenNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.signing-key-unresolvedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.not-a-memberNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.membership-missing-capabilityNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.minter-missing-capabilityNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.operator-requiredNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.credential-unknownNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.credential-revokedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.credential-expiredNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.credential-liveNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.credential-missing-capabilityThe deploy credential is good, and it does not carry a capability word this route asks for.
Mint one that carries the word. An MCP tool names every word it is short of at once, so you widen the credential once rather than coming back for each.
session-requiredNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.app-outside-credential-scopeThe deploy credential carries the word the route asks for and is restricted to named Apps. This App is not one of them.
Point the pipeline at an App the credential was minted for, or mint one naming this App with
--app. Adding capability words changes nothing, because the restriction is over which Apps the credential reaches. Regenerating keeps the restriction it has.credential-already-revokedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.oauth-client-unknownNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.client-document-unusableNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.client-document-not-fetchedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.redirect-uri-unregisteredNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.credential-outside-its-resourceNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.Not written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.function-liveNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.app-liveNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.target-restrictedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.target-heldNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.deploy-abandonedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.cli-login-redirect-refusedNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.cli-login-request-spentNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.cli-login-code-unusableNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.cli-session-unusableNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.session-endedSomebody ended your sessions in this workspace after you signed in. The token you sent, and every sign-in made before that moment, no longer lets you in here. You are still a member, and your other workspaces are not affected.
Sign in again. In a terminal, run
npx wawesome login.support-cap-reachedThe workspace has written to support as many times today as a day allows. The refusal says how many that is.
The count starts again at midnight UTC. If you are waiting on an answer, reply to the copy of what you sent rather than sending it again.
invitation-unusableNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.invitation-expiredNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.invitation-for-another-addressNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.already-a-memberNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.last-ownerThe act would leave the workspace with nobody at
owner. That is a move to another standing, a removal, or somebody's own request to leave. A workspace has one owner, and what it pays and the address its customers reach are that person alone.Nothing here. Ownership cannot be handed to somebody else yet, so the owner stays the owner. Move or remove anybody else instead.
custom-domain-requiredThe App being handed to another workspace has no custom domain answering yet. Its address today is built from your workspace name, so the site would change address the moment it changed hands, which is the one thing a handover is for.
Attach a domain the recipient's business owns, wait for it to serve, and offer the App then.
transfer-in-flightThe App is already being handed to somebody. One App goes to one workspace, and once the receiver has accepted, deploys into it are paused until the transfer finishes. A deploy mid-transfer writes files the copy was already taking. The App is still serving throughout.
Take the offer that stands back, or wait for the transfer to finish, then deploy.
owner-requiredThe act belongs to whoever owns the workspace, and you are in it at another standing. Handing an App to another workspace is the one act on an App that only the owner does.
Ask whoever owns the workspace to do it. No wider credential reaches this, because it is about standing rather than about a capability.
rate-limitedToo many requests this minute. As a
reasonon the management API it means one caller asked more often than one caller may: every route shares one budget, and a read spends what a write spends. The same words arrive asx-wawesome-errorat your own public address, where they mean a visitor went over your site's rate limit instead. The Limits page has both sets of numbers.Wait and send it again. The management refusal carries
Retry-Afterin seconds, so read that rather than retrying at once.assistant-offNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.assistant-daily-capNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.assistant-monthly-budgetNot written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.Not written up here yet.
Read the
errorfield the gateway sent beside it. That says what happened, in prose.drafts-exhaustedYou already have as many open drafts on this Function as one owner can have. The owner is the person or the deploy credential that opened them. The refusal carries
allowancewith the cap and how many are open.Discard a draft you no longer need, or keep working in one you have.
list_draftsmarks yours.draft-owner-requiredThe draft belongs to somebody else. Anyone in the workspace can list a draft and read its files, but only the person or deploy credential that opened it can change or discard it.
Ask its owner, or open a draft of your own.
draft-moved-onThe draft was edited after the revision this promote names. Promoting it would ship changes nobody approved, so nothing went live.
Show the person the draft as it is now, and promote again with its current
revision.draft-conflictsSince the draft was opened, the live version changed some of the same files the draft changed. The refusal names those files. The platform never merges text inside a file, so nothing went live.
Open a new draft, which starts from the live version, and make the change again there. Then discard this one.