Reference

Error codes

Every refusal code Willo's MCP server returns and every response a webhook trigger sends, with what each one means.

Generated from Willo's codeOpen in ClaudeOpen in ChatGPT
On this page

A refused MCP call returns an error result whose code is one of these. The message beside it always says what to do. Webhook responses are listed below and on Webhook request format.

Connection refusals

Before any tool runs, the server checks the token and the business. A failed check is an HTTP error whose JSON body is {"error": code, "message": …}; the same code is in the WWW-Authenticate header.

StatusCodeMeaning
401invalid_tokenThe Authorization header is missing, or the token is mistyped or unknown.
401no_accessThe person who created the token no longer has access to the business.
401token_expiredThe token's expiry date has passed. Create a new one.
401token_revokedThe token was revoked on the dashboard. Create a new one.
403instance_inactiveThe business is paused or closed.
403instance_suspendedThe business is suspended.
403origin_not_allowedThe request came from a web page origin Willo's MCP server doesn't accept. Connect from a desktop or command-line client.
403plan_lapsedThe business's plan has lapsed, so its agents are paused too.
403plan_requiredThe business's plan doesn't include connecting AI agents. An owner or admin can upgrade on the Billing page; existing tokens work again after.
429rate_limitedToo many requests in the last minute. Wait for Retry-After.
503unavailableWillo's MCP server is starting up. Retry in a few seconds.

MCP refusal codes

CodeMeaning
approval_pendingWillo's chat is waiting on a person to answer a card, so a new task would skip it. Ask them to answer it first.
approved_runningThe approved call is still running on Willo's side. Check it with willo_get_approval. Do not call the tool again for it.
binaryThe file is binary and cannot be returned as text.
budget_exceededThe business has hit its per-minute limit for this kind of call (site code, backend management or Stripe reads). Wait and retry.
credential_in_sourceFunction source holds a hard-coded credential. Read it from an environment secret instead.
docs_unavailablewillo_docs could not reach the docs site. Retry shortly, or read www.willo.ai/docs directly.
draft_unavailableThe draft branch could not be confirmed, so nothing was written. Willo never falls back to the live site.
edit_failedAn edit's old text was not found exactly once in the file. Read the file and retry.
gate_changedThe rules for the call changed between the approval and the retry. Call again for a new card.
gate_unreadableWillo could not read whether the business is drafting, so nothing was written. Retry in a minute.
github_budgetGitHub is rate-limiting writes for now. Retry in a few minutes.
github_errorGitHub, which holds the site's code, returned an error. Nothing was written. Retry shortly.
github_not_configuredCode access is not available on this environment right now.
github_unavailableThe draft branch could not be read from GitHub just now. Retry in a minute.
handler_refusedWillo's rules refused the action itself (the same refusal chat would give). The message says why.
internal_errorSomething failed on Willo's side. Retry, and contact support@willo.ai if it persists.
interruptedThe server restarted while the call ran. Check the result before retrying.
invalid_argumentsAn argument is missing, has the wrong type, or is not one the tool takes. The message names it.
invalid_importsThe function's import map is not valid JSON.
invalid_package_jsonpackage.json would no longer be a valid JSON object.
invalid_pathThe path is not a safe path inside the site's code.
is_directoryThe path is a directory, not a file.
lane_busyWillo's chat for this business is busy with another turn. Retry shortly.
needs_approvalA read tool was asked to do something chat would stop for. It is refused rather than run unasked.
no_repoThe business has no code repository yet. The first build creates it.
no_threadThe business has no chat thread yet. The owner opens Willo's chat once, then retry.
not_a_fileThe path is a link or submodule, not a regular file.
not_foundThe file, row, function or approval does not exist where you asked.
not_textThe file is not a text file, so it cannot be edited as text.
offset_past_endThe line offset is past the end of the file.
pending_approvalThe call needs a person's approval. The result carries a dashboard link and a request id. Call the same tool with the same arguments after they approve.
rankThe tool changes the business and the person who created the token is a viewer. Acting needs editor access or higher.
rate_limitedToo many calls in the last minute, for this token or for the business. Wait and retry.
repo_busyA site deploy is finishing, and writing to the live site now would break it. Retry in a minute.
scopeThe tool changes the business and the token is read-only. Create a read + act token.
secret_in_contentThe content you are writing holds a value shaped like an API key or token. Secrets never go in files, function source or SQL.
secret_in_messageThe willo_task message holds a value shaped like an API key or token. Remove it. Secrets are added on the dashboard.
sha_requiredReplacing an existing file needs the sha willo_read_file returned for it.
stale_shaThe file changed since you read it. Read it again and retry with the new sha.
still_savingThe write is still being saved. Check with willo_read_file before writing it again.
task_runningThis token already has a willo_task in progress. Wait for it with its turn_id.
too_largeThe file or content is over the size the tool accepts.
too_many_cardsThis token already has the most approval cards it may hold open. Ask the person to answer them first.
too_many_changesThe change touches more packages than one approval card can list. Split it up.
unknown_toolNo tool by that name exists on the server, or this token cannot see it.
write_cappedThe business has taken the most agent changes it accepts in a minute. Wait and retry.

Webhook responses

The body is JSON: {"status": …} on success, {"error": …} on a refusal.

StatusCodeMeaning
200duplicateA repeat of a call already accepted (same Idempotency-Key, or the same body on the same UTC day). No second run.
202queuedThe call was accepted and one run is queued.
400invalid_bodyThe body could not be parsed as the Content-Type it declares.
401invalid_secretThe URL's secret is wrong.
401signature_expiredThe signature's timestamp is outside the allowed window.
401signature_invalidThe signature does not match the body.
401signature_malformedThe X-Willo-Signature header is not in the t=<unix>,v1=<hex> format.
401signature_requiredThe trigger requires a signature and the call carries no X-Willo-Signature header.
404unknown_triggerNo active trigger has this URL. It was rotated, revoked, archived, or never existed.
409program_not_activeThe program is paused, still a draft, or no longer uses a webhook trigger.
413payload_too_largeThe body is over the size limit.
415unsupported_media_typeThe Content-Type is not JSON, form-encoded or plain text.
429daily_capThe program has reached its runs-a-day limit. Calls run again tomorrow. Sent with Retry-After.
429queue_fullThe program has the most events it may hold waiting. Retry after Retry-After. Sent with Retry-After.
429rate_limitedToo many calls in the last minute. Wait for Retry-After. Sent with Retry-After.
503unavailableWebhook triggers are temporarily unavailable. Retry later, honouring Retry-After when it is sent.