# Refusals

A refusal is BakedBrie saying no, with a stable code. Find the code on this page (each code is its own heading, so `/docs/refusals#<code in lowercase>` links straight to it).

## How a refusal looks

From an MCP tool, the result has `isError: true` and:

```json
{"error":{"code":"REVISION_CONFLICT","message":"This card changed. Refresh before applying your edit.","fix":"Someone changed it first. Read it again and retry with the current revision.","current_revision":"42"},"request_id":"019a..."}
```

From the REST API, the HTTP status is 4xx or 5xx and the body is:

```json
{"error":{"code":"REVISION_CONFLICT","message":"...","fields":[],"retryable":false},"request_id":"...","receipt_id":null}
```

General rules:

- Read `code`, then `fix` if present. The `message` is for people.
- Do not retry a refusal unchanged. Only codes marked "retry" below are worth retrying as is.
- When you retry a mutation, reuse its `request_id` (MCP) or `Idempotency-Key` (REST). Never reuse one for a different call.
- A refusal changed nothing, unless the entry says otherwise.
- Never ask the user for a secret in chat to get past a refusal.

## Connection and token

### UNAUTHENTICATED

HTTP 401. The bearer token is missing, malformed, unknown, revoked or expired (tokens last 90 days). The header must be exactly `Authorization: Bearer bbk_...`, sent once.

Next: check that `BAKEDBRIE_TOKEN` is set in the shell the client started from, then restart the client. If the token was revoked or expired, ask the user to mint a new one ([Tokens](/docs/tokens-and-runner)).

### AMBIGUOUS_AUTHORITY

HTTP 400. The request carried both a browser session cookie and a bearer token.

Next: send only the bearer token.

### API_TOKENS_DISABLED

HTTP 409. API tokens are turned off on this BakedBrie server.

Next: nothing you can fix. Tell the user.

### MCP_DISABLED

HTTP 409. The MCP endpoint is turned off on this server.

Next: nothing you can fix. Tell the user. The REST API may still work if tokens are on.

### INTERACTIVE_SESSION_REQUIRED

HTTP 403. This action is for a signed-in person in the web app, not a token. Examples: minting or revoking tokens, answering an agent's question, archiving or renaming a board through the web routes, disconnecting a runner, or a route tokens can never call. Also sent when `/mcp` is called without an API token.

Next: ask the user to do it in the BakedBrie app. Do not look for a workaround.

### TOKEN_WORKSPACE_MISMATCH

HTTP 403. The request named a workspace (`X-Workspace-Id`) the token does not belong to.

Next: leave out `X-Workspace-Id`; the token's own workspace is used. For another workspace, the user mints a token there.

### TOKEN_READ_ONLY

HTTP 403. This token has the Read only preset, and the call would change something.

Next: tell the user. If they want you to make changes, they mint a Full control token in Settings, Apps and API.

### TOKEN_RUNNER_ONLY

HTTP 403. This is a runner key. It works only with `bakedbrie-runner`.

Next: use a Full control or Read only token for MCP and REST.

### TOKEN_PRESET_UNKNOWN

HTTP 403. The token has a preset this server does not recognize.

Next: the user mints a new token.

### TOKEN_REQUIRED

HTTP 403. The action (for example preparing or filling a secret drop) needs an API token, and the caller is not using one.

Next: call it with the token, and run the secret drop command with the same `BAKEDBRIE_TOKEN`.

### CAPABILITY_OFF

HTTP 409. The feature this tool or route needs is off in this workspace. Variants of the message name the feature, for example "API destinations are off in this workspace" or "Check rules and the review option are off in this workspace".

Next: nothing to retry. Call `whoami`, see which capabilities are on, and plan without this one. Never call a tool for a capability that is off.

### FORBIDDEN

HTTP 403. The token's member lacks this permission. Examples: a viewer creating a board, a non-admin setting the workspace AI account or pausing dispatch, attaching someone else's AI account, managing a board without manage permission.

Next: tell the user who can do it (a board admin or workspace owner or admin).

### NOT_FOUND

HTTP 404. The object does not exist, is gone, or this token cannot see it. BakedBrie does not say which, on purpose.

Next: list again (`list_boards`, `list_cards`, `whoami`) to get a current id. Do not guess ids.

### RATE_LIMITED

HTTP 429. The token or workspace hit its request rate. The REST answer has a `Retry-After` header in seconds.

Next: retry: wait for `Retry-After`, then send the same call again with the same `request_id` or `Idempotency-Key`.

### RATE_BUDGET_UNAVAILABLE

HTTP 503. Request capacity could not be checked.

Next: retry later with the same `request_id`.

## Request format

### INVALID_INPUT

HTTP 422 (MCP: a tool result). An argument is missing, has the wrong type, or breaks a limit. From a tool, `fix` names the fields, for example `Fix: board_id Invalid uuid`. Some tools also say which field an action needs, for example "create needs board_id, name, days, at_time, timezone and card_titles" or "Pass exactly one of drop_id or secret".

Next: fix the arguments against the tool's input schema and call again.

### INVALID_JSON

HTTP 400. The body is not valid JSON.

Next: send valid JSON with `Content-Type: application/json`.

### BODY_TOO_LARGE

HTTP 413. A JSON request is over 5,000,000 bytes.

Next: send less. For files, use `attach_local_file` or `prepare_transient_upload` instead of putting bytes in JSON.

### UNSUPPORTED_MEDIA_TYPE

HTTP 415. Wrong `Content-Type`. JSON routes need `application/json`. A secret drop's `PUT` needs `text/plain`.

Next: fix the header. For secret drops, run the `command` from `prepare_secret` exactly as given.

### IDEMPOTENCY_KEY_REQUIRED

HTTP 400. A REST mutation was sent without an `Idempotency-Key` header. (MCP tools add one for you.)

Next: send a unique `Idempotency-Key` (1 to 200 printable characters) and reuse it only for retries of the same call.

### INVALID_IDEMPOTENCY_KEY

HTTP 400. The `Idempotency-Key` is empty, over 200 characters, or has characters outside printable ASCII.

Next: use a UUID.

### IDEMPOTENCY_CONFLICT

HTTP 409. This `request_id` or `Idempotency-Key` was already used for a different call.

Next: use a new `request_id` for the new call. Reuse an old one only to retry exactly the same call.

### REVISION_REQUIRED

HTTP 428. A REST change needs the current revision in `If-Match` and none was sent. (MCP tools read and send it for you.)

Next: read the board or card, then send `If-Match: "<revision>"`.

### INVALID_REVISION_HEADER

HTTP 400. `If-Match` is not one quoted revision.

Next: send exactly `If-Match: "<revision>"`.

### INVALID_CURSOR

HTTP 400. The `cursor` is not one this list gave out, or it is stale.

Next: list again from the first page without `cursor`.

### INVALID_STATE

HTTP 409. The request does not fit the object's current state. Examples: "This list cannot be paged any further right now", "This list holds too many cards to reorder", "Only paused or repaired blocked work can resume".

Next: read the object again and choose an action that fits its state.

### INTERNAL_ERROR

HTTP 500. The request could not be completed.

Next: do not blindly repeat a change. Read the object (or `list_results` for deliveries) to see whether it happened, then retry with the same `request_id` if it did not.

### TOOL_FAILED

MCP only. A tool failed without a more specific code.

Next: read the message. Check the current state with a read tool before trying again with the same `request_id`. If it persists, tell the user.

### SETUP_FAILED

MCP only, from `setup_board`, when a step fails without its own code. The message ends with `Created so far: {...}` listing what was already made. (When a step has its own code, that code is returned with the same `Created so far` list.)

Next: tell the user what was created. Either finish the rest with the individual tools, or undo by hand. Do not call `setup_board` again with the same inputs, or you get a second board.

## MCP protocol errors

These are JSON-RPC errors, not tool results.

| Code | Message | Meaning and next step |
|---|---|---|
| `-32600` | `Invalid Request` or `A request id is required` | The JSON-RPC body is malformed or has no `id`. Fix the request. |
| `-32601` | `Method not found` | The method is not supported. BakedBrie supports `initialize`, `ping`, `tools/list`, `tools/call`, `prompts/list`, `prompts/get`. |
| `-32602` | `Unknown tool`, `Invalid tool parameters` or `Unknown prompt` | Call `tools/list` or `prompts/list` for current names. A tool missing from `tools/list` has its capability off. |

## Boards, columns and cards

### REVISION_CONFLICT

HTTP 409. Someone changed the board, card, destination, endpoint or guidelines after you read it. Often carries `current_revision`.

Next: read it again, check your change still makes sense, and retry. For `manage_board_guidelines`, `manage_destination` and `manage_inbound_endpoint`, pass the new revision as `expected_revision`.

### PREVIEW_CHANGED

HTTP 409. What you previewed is no longer current: the card changed since `preview_move`, or the file under review changed since `get_review`.

Next: preview again (`preview_move`) or read again (`get_review`), show the user the new content, and use the new `preview_hash` or `intent_hash`.

### BOARD_UNAVAILABLE

HTTP 409. The board is archived.

Next: tell the user and work on another board.

### STAGE_UNAVAILABLE

HTTP 409 or 422. The column is not usable here. Examples: "Use a column on this board", "Use two different columns on this board" (a rule's when and then columns must differ), "Use a fail column on this board that is not the column the rule starts in", "Choose a current entry stage".

Next: call `read_board` for current column ids and pick valid ones.

### OWNER_UNAVAILABLE

HTTP 409. The owner you named cannot own this card: not an active member with work permission on this board, not an active agent, or not a named automation. For inbound endpoints: the endpoint owner lost access to the board.

Next: pick an active member or agent on this board. For an endpoint, update it with an owner who can work on the board.

### STAGE_NOT_EMPTY

HTTP 409. The column you asked to delete still holds cards. `details.cards` is how many.

Next: move the cards to another column (or let the user do it), then delete the column.

### STAGE_IN_USE

HTTP 409. A rule, check, schedule, Cards from Slack channel, inbound endpoint or intake source names the column you asked to delete. `details` counts each kind.

Next: change or remove what uses the column, then delete it. The first column and Done can never be deleted (`INVALID_INPUT`).

### CARD_TERMINAL

HTTP 409. The card is completed or canceled, so its work cannot change.

Next: ask the user whether to reopen it in the app, or create a new card.

### COMMAND_UNAVAILABLE

HTTP 422. This command is not available for the card in its current state.

Next: `read_card` and choose a command that fits.

## Agents, rules, schedules and setup

### AGENT_INVALID

HTTP 422. The agent has no instructions, so it cannot be published.

Next: `manage_agent` with `action: "update"` and `instructions`, then `publish_agent`.

### AGENT_NOT_PUBLISHED

HTTP 409. The agent has never been published.

Next: `publish_agent` first (with the user's yes if it can send outside BakedBrie).

### AGENT_RETIRED

HTTP 409. The agent is retired and cannot work or be changed.

Next: create a new agent with `create_agent_draft`.

### AGENT_UNAVAILABLE

HTTP 422. The agent is not on this board.

Next: use an agent from this board (`manage_agent` `get` shows its `board_id`).

### AI_ACCOUNT_UNAVAILABLE

HTTP 409. The AI account is not connected or not usable.

Next: `list_ai_accounts`, then `check_ai_account` with `action: "recheck"`. If it is failing, the user reconnects it.

### RULE_INVALID

HTTP 422. `max_rounds` was given without `fail_stage_id`. Rounds apply only to check rules.

Next: add `fail_stage_id`, or drop `max_rounds`.

### INVALID_SCHEDULE

HTTP 422. The days, time or timezone are not valid.

Next: days from `mon` to `sun`, `at_time` as `HH:MM` (24-hour), and an IANA timezone such as `America/Toronto`.

### SCHEDULE_PAUSED

HTTP 409. The schedule is paused, so `run_now` cannot run it.

Next: `manage_schedule` with `action: "resume"` (with the user's yes), then `run_now`.

### SETUP_INVALID

HTTP 422. A setup can only record objects on its own board.

Next: this points to a bug in how setup was called. Tell the user; build the rest with the individual tools.

### UNDO_EXPIRED

HTTP 409. `undo_setup` works for 24 hours after setup, and only if nobody edited the board since.

Next: undo by hand: pause the rule and schedule (`publish_workflow` `pause`, `manage_schedule` `pause`), retire the agent (`manage_agent` `retire`), disable the destination, and ask the user to archive the board in the app.

### UNDO_UNAVAILABLE

HTTP 409. This setup was already undone.

Next: nothing to do.

### GUIDELINES_UNAVAILABLE

HTTP 409. Board guidelines are not available on this server yet.

Next: put the guidance in the agent's instructions instead.

### DISPATCH_PAUSED

HTTP 423. All runs, deliveries and media jobs in this workspace are paused (emergency stop).

Next: tell the user. Only if they agree, call `resume_workspace_dispatch`.

## Secrets and AI accounts

### SECRET_DROP_EXPIRED

HTTP 410. The drop expired (10 minutes), was already used, belongs to another token, or was prepared for another purpose or kind. For inbound signing secrets, the drop must be prepared with `kind: "inbound_signing"` and `purpose: "connection"`.

Next: call `prepare_secret` again with the right `kind` and `purpose`, run the new command, and pass the new `drop_id`.

### UPLOAD_ORIGIN_UNKNOWN

HTTP 503. The server does not know its own public API address, so it cannot build a secret drop or upload command.

Next: nothing you can fix. Tell the user this server is misconfigured.

### SECRET_STORE_UNAVAILABLE

HTTP 503. Secret storage is not configured on this server.

Next: tell the user. Retry later.

### SECRET_UNAVAILABLE

HTTP 409. A stored signing secret can no longer be read.

Next: set the secret again (`manage_inbound_endpoint` `update` with a new `signing_secret` from `prepare_secret`).

## Destinations

### DESTINATION_TYPE_UNAVAILABLE

HTTP 409. This destination type is not allowed here. Examples: only GitHub, S3/R2, Google Drive and API destinations exist; a work folder must be an S3/R2 destination; a board hook needs an API destination.

Next: use a destination of the type the message names.

### DESTINATION_UNAVAILABLE

HTTP 422. The destination is not an active API (webhook) destination in this workspace (for an inbound endpoint's reply or file fetch).

Next: `manage_destination` `get` to check it; create or re-enable an API destination and use its id.

### CREDENTIAL_REQUIRED

HTTP 422. Changing an API destination's preset, base URL or auth needs its credential again in the same request.

Next: prepare a new secret drop and pass `credential: {"drop_id": "..."}` in the same `update`.

### CREDENTIAL_INVALID

HTTP 409. The Google service-account key is not valid JSON, lacks `client_email` or `private_key`, or cannot sign.

Next: ask the user for the right key file in their environment and send it through a new secret drop.

### CONFIG_INVALID

HTTP 409. The stored API destination configuration is not valid, so a board hook cannot use it.

Next: fix it with `manage_destination` `update`, then set the hook again.

### ACTION_NOT_ALLOWED

HTTP 422. A board hook cannot run the `deliver` action.

Next: set the destination as the board or card destination for delivery; use a hook for other actions.

### ACTION_NOT_FOUND

HTTP 422. The API destination has no action with that name. The message lists the actions it has.

Next: pick one of the listed actions for `destination_action`.

### OAUTH_STATE_INVALID

HTTP 409. For Google Drive: the sign-in in this browser was started for another destination. For Add to Slack: the link expired or was already used.

Next: open the consent link of the destination you meant (`oauth.consent_url` from `manage_destination` `get`), or start Add to Slack again from BakedBrie.

### OAUTH_STATE_MISMATCH

HTTP 409. A Google Drive sign-in can only finish in the browser, and for the person, that opened the destination's consent link, within 10 minutes, once. This answer means it did not start in this browser, it expired, it was already used, or it came from an API token (`complete_oauth` over MCP cannot finish it).

Next: give the person `oauth.consent_url` from `manage_destination` `get` to open in a browser signed in to BakedBrie; the connection finishes there.

### GOOGLE_OAUTH_UNAVAILABLE

HTTP 409. Google sign-in for destinations is not configured on this server.

Next: use `auth: "service_account"` for Google Drive, or another destination type.

### GOOGLE_SCOPE_REFUSED

HTTP 409. Google granted a broader scope than `drive.file`, so the connection was not saved.

Next: ask the user to consent again and grant only the requested access.

### GOOGLE_TOKEN_REFUSED

HTTP 409. Google refused the authorization or returned no usable token.

Next: start the connection again with a fresh consent link.

### GOOGLE_UNREACHABLE

HTTP 502. Google did not answer.

Next: retry later.

### Problems in a destination test

`manage_destination` with `action: "test"` succeeds and returns `ok` and a `problems` list instead of refusing:

| Problem | Next |
|---|---|
| `DESTINATION_DISABLED` | The destination is turned off. Create a new one and set it as the board default. |
| `CREDENTIAL_MISSING` | Send the credential through `prepare_secret` and `update`. |
| `CONFIG_INVALID` | Fix the configuration with `update`. |
| `SLACK_INSTALL_REVOKED` | BakedBrie is not installed in that Slack workspace. Ask an owner or admin to click **Add to Slack** in **Settings**. |
| `SLACK_CHANNEL_NOT_JOINED` | The bot is not in the Slack channel. Type `/invite @BakedBrie` (or your own app's name) in the channel, then test again. |

Delivery failures after a run are not refusals. They show on the delivery receipt in `list_results`; retry a failed or outcome-unknown delivery with `redeliver`.

### TEST_CALL_RATE_LIMITED

HTTP 429. A destination's connection can be checked once every 10 seconds and 20 times an hour. `Retry-After` says when.

Next: wait, then call `manage_destination` action `test_call` again.

### TEST_CALL_PATH_INVALID

HTTP 422. The check's path must stay under the destination's base URL: printable characters, no spaces, no `#`.

Next: pass a path such as `/me`.

### TEST_CALL_NOT_FOUND

HTTP 404. That check is gone (checks are kept 7 days) or belongs to another destination.

Next: start a new one with `test_call` and `path`.

### DESTINATION_DISABLED

HTTP 409. The destination is turned off, so it cannot send, be checked or sign in.

Next: create a new destination and make it the board default.

### OAUTH_NOT_CONNECTED

A custom API that signs in with OAuth has no working sign-in yet.

Next: give the person `oauth.consent_url` from `manage_destination` `get` to open in a browser signed in to BakedBrie, or, for client credentials, wait until `oauth_grant.state` is `connected`.

### OAUTH_RECONNECT_NEEDED

The service stopped accepting the sign-in (for LinkedIn, after 60 days). Deliveries fail until the person signs in again.

Next: give the person `oauth.consent_url` from `get` again (the web app shows Sign in again).

### OAUTH_EXCHANGE_FAILED

The service refused to finish the sign-in: usually a wrong client id or secret, a redirect URL the OAuth app does not list, or a code that expired.

Next: check the OAuth app's settings and the destination's `client_id`, then sign in again.

### OAUTH_PROVIDER_UNREACHABLE

The service's token URL did not answer.

Next: try again later. Nothing was sent to the API.

### OAUTH_ISSUER_MISMATCH

The sign-in came back from a different issuer than the destination's `issuer`.

Next: check `issuer` against the service's docs, then sign in again.

### OAUTH_REVOKE_FAILED

The service did not confirm it revoked the sign-in. BakedBrie deleted its own copy anyway.

Next: remove the app's access in the service's own settings if you want to be sure.

### TEMPLATE_INVALID

A value in a custom API step could not be filled in (a missing field, an unknown placeholder or filter). Nothing was sent for that step.

Next: `manage_destination` action `preview` with the card shows which step and value; fix the definition or the card's result.

### OUTCOME_UNKNOWN

A write was sent but its answer never came back, so BakedBrie cannot know whether it landed. It is never sent again.

Next: look at the service. `redeliver` looks for it when the step has `reconcile`; otherwise do it by hand if it did not land.

### DESTINATION_AUTH_FAILED

The service answered 401 or 403: the key or sign-in is wrong, expired or lacks a permission.

Next: replace the credential with `manage_destination` `update`, or sign in again for OAuth.

## Reviews

### MAKER_CANNOT_APPROVE

HTTP 403. On a shared board, the person who made the file cannot approve it. Your token acts as that person.

Next: tell the user another board member (or the named reviewer) must approve.

### NOT_NAMED_REVIEWER

HTTP 403. The board names one reviewer, and the token's member is not that person.

Next: tell the user who the reviewer is (`get_review` names them).

### REVIEW_DECIDED

HTTP 409. The review was already decided or superseded by a newer version.

Next: `list_reviews` for the current item.

## Files and media

### TYPE_NOT_ALLOWED

HTTP 422. The file type is not supported (SVG and look-alike files are always refused).

Next: tell the user; convert the file to a supported type such as PNG, JPEG, PDF or MP4.

### UPLOAD_UNAVAILABLE

HTTP 404. The upload link was used or expired (15 minutes).

Next: call `attach_local_file` or `prepare_transient_upload` again and use the new link once.

### UPLOAD_STORAGE_UNAVAILABLE

HTTP 503. File uploads are not available on this server.

Next: use `attach_link` to point at the user's own storage instead.

### PAIRING_UNAVAILABLE

HTTP 404. The device pairing code was used or expired (10 minutes).

Next: call `pair_device` again.

### DEVICE_SIGNATURE_INVALID

HTTP 401. A request from the drop helper was not signed by its device key.

Next: pair the helper again with `pair_device`.

### GENERATION_PROVIDER_UNSUPPORTED

Not an HTTP error: it shows as the `refusal_code` of one output in a run result (`list_results`, `get_output`). The agent asked for an image, but the run is paid by an Anthropic AI account (Anthropic cannot make images), or by the local runner, which makes its own files on the user's computer. Nothing was sent to a provider and nothing was charged.

Next: tell the user. To have BakedBrie make images, they bind an OpenAI AI account to this agent, board or workspace (`bind_ai_account`), then run the card again.

### WORK_FOLDER_REQUIRED

Not an HTTP error: it shows as the `refusal_code` of one output in a run result. The agent asked for an image, but BakedBrie keeps a generated image only as a file in the board's work folder, and this board has none. Nothing was sent to a provider and nothing was charged.

Next: tell the user. They set a work folder for the board (`set_work_folder`), then run the card again.

### WORK_FOLDER_UNAVAILABLE

Not an HTTP error: it shows as the `refusal_code` of one output in a run result. The board's work folder is disabled or cannot be written to, so BakedBrie did not make the image (nothing was sent or charged). If the folder failed after an image was made, the output carries a `generation` receipt: it was charged once and is not made again.

Next: tell the user. They fix or reconnect the work folder destination (`manage_destination`), then run the card again.

### GENERATION_KIND_UNAVAILABLE

Not an HTTP error: it shows as the `refusal_code` of one output in a run result. The agent asked for audio or video; BakedBrie can only make images for now. Nothing was sent or charged.

Next: ask for an image instead, or have the user make the audio or video elsewhere and attach it to the card.

### GENERATION_TIME_LIMIT

Not an HTTP error: it shows as the `refusal_code` of one output in a run result. The run spent its time on earlier images, so BakedBrie did not start this one (every paid call must finish inside the run's time). Nothing was sent or charged for it.

Next: ask for the remaining images in a new run, or ask for fewer images per run.

### CALL_INTERRUPTED

Shows on a run (`error_code`) or as the `refusal_code` of one generated output. The AI call was sent, then timed out or lost its connection. The provider may have run it and charged for it, so BakedBrie never sends it again on its own.

Next: check the result. If the output is missing, ask the user before running the card again, since a new run is a new paid call.

### AI_ACCOUNT_REQUIRED

HTTP 409 on a run (`error_code`), or the `refusal_code` of a generated output. No active AI account is bound to this agent, board or workspace, so nothing can pay for the call.

Next: `list_ai_accounts`; the user connects one (`connect_ai_account`) and binds it (`bind_ai_account`). A waiting run starts again once it is bound.

### File states on a card

An upload that reaches BakedBrie but is not accepted shows on `list_card_files` as `refused` with one of these codes:

| Code | Meaning | Next |
|---|---|---|
| `TYPE_NOT_ALLOWED` | The bytes are not a supported type | Convert the file |
| `EMPTY_FILE` | No bytes arrived | Upload again |
| `SIZE_LIMIT` | Over the size limit | Send a smaller file |
| `HASH_MISMATCH` | The bytes do not match the `sha256` you gave | Recompute size and sha256 on the device, then attach again |
| `PROCESSING_FAILED` | The file could not be processed | Try again once; if it repeats, tell the user |

## Connections

Codes from `manage_connection`, `manage_board_connection`, `manage_connection_step`, `request_connection` and `manage_connection_request` (and their REST routes). See [Concepts: Connections](/docs/concepts#connections). No refusal on this page sent a call or counted money, unless the entry says so.

### REQUEST_ID_REQUIRED

HTTP 422 (MCP). `request_connection` action `create` was called without `request_id`. Nothing was done.

Next: call again with `request_id` set to a new UUID. Reuse that same `request_id` only to retry this same create: a retry returns the same request and never makes a second call.

### CONNECTION_LIMITS_WEB_ONLY

HTTP 403. Limits and the monthly ceiling can be set or raised only by a person in the BakedBrie web app. An API token or an agent can only lower them. Money fields on `attach` are refused the same way.

Next: give the person `limits_link` (from `manage_board_connection` `get`) or `ceiling_link` (from `manage_connection` `get`) to open. To lower a limit, send a value at or below the current one with `lower_limits` or `lower_ceiling`.

### CONNECTION_LIMITS_NEED_A_PERSON

HTTP 409. No limits are set on this board for this connection (or no monthly ceiling on the connection), so nothing that can cost money may run. No call was sent. In a `request_connection` preview it appears in `problems` instead.

Next: tell the person "Only a person can let a board spend" and give them `limits_link` (and `ceiling_link` if the ceiling is not set). Try again after they set them.

### CONNECTION_NOT_FOUND

HTTP 404. The connection, attachment, step or request does not exist, was removed, or this token cannot see its board.

Next: list again (`manage_connection` `list`, `manage_board_connection` `list`) for a current id.

### CONNECTION_NAME_TAKEN

HTTP 409. Another connection in this workspace already has this name.

Next: pick another name, or update the existing connection.

### CONNECTION_NOT_CUSTODIAN

HTTP 403. Only the person who created the connection, or a workspace owner or admin, can change it, check its key, attach it or preview it saved. Other members see a summary without the definition.

Next: ask the custodian, or create your own connection with your own key.

### CONNECTION_IN_USE

HTTP 409. The connection has calls that are not finished, so it cannot be removed.

Next: wait for them or cancel them (`manage_connection_request`), or `disable` it now (new calls stop, sent ones are still collected).

### CONNECTION_OPERATION_IN_USE

HTTP 409. The new definition drops an operation a board still uses.

Next: remove the operation from each board first (`manage_board_connection` `update`), then update the connection.

### CONNECTION_DISABLED

HTTP 409. The connection is turned off. Calls already sent are still collected.

Next: `manage_connection` action `enable` if the custodian agrees.

### CONNECTION_NO_KEY_CHECK

HTTP 422. The definition has no `key_check`.

Next: add `"key_check": {"path": "/a/harmless/get"}` with `manage_connection` `update`, or skip the check.

### CONNECTION_KEY_CHECK_RATE

HTTP 429. Key checks are limited to one every 10 seconds and 20 an hour per connection.

Next: wait, then `check_key` again.

### CONNECTION_HANDLE_TAKEN

HTTP 409. Another attachment on this board already uses this handle.

Next: pick another handle.

### CONNECTION_OPERATION_UNKNOWN

HTTP 422. The connection has no operation with this key.

Next: read the connection's `operations` (`manage_connection` `get`) and use one of their keys.

### CONNECTION_NOT_ALLOWED

HTTP 403. This board has no attachment for that connection here, or it does not allow this person, agent or column (`people`, `agent_ids`, `stage_ids`).

Next: check the attachment with `manage_board_connection` `get`. A board manager who is the custodian can change it.

### CONNECTION_OPERATION_NOT_ALLOWED

HTTP 403. The attachment does not allow that operation, or the step names one it does not allow.

Next: add the operation to the attachment's `operations` (`manage_board_connection` `update`).

### CONNECTION_INPUT_INVALID

HTTP 422. An input is missing, unknown, fixed by the board, or does not fit its field (length, range or choice). The message names the input. For a column step: a template uses a value that is not allowed, or a required input has no template.

Next: fix that input and preview again. Fixed inputs are never sent by the requester.

### CONNECTION_FILE_INVALID

HTTP 422. A file role names a file that is not a processed file of this card, or its type or size does not fit the role.

Next: pick a file from this card (`list_card_files`) of an allowed type and size.

### CONNECTION_CARD_LIMIT

HTTP 409. This card has used all its calls to this connection (the per-card limit counts over the card's whole life). No call was sent.

Next: finish the card without the call, or ask a person to raise the per-card limit in the web app (`limits_link`).

### CONNECTION_MONTHLY_CALLS_LIMIT

HTTP 409. The board has used all its calls to this connection this month. No call was sent.

Next: wait for next month, or ask a person to raise it in the web app (`limits_link`).

### CONNECTION_MONEY_LIMIT

HTTP 409. The board's monthly money limit for this connection would be passed by this call's most it can cost. No call was sent.

Next: ask a person to raise it in the web app (`limits_link`), or finish without the call.

### CONNECTION_CEILING_LIMIT

HTTP 409. The connection's monthly ceiling across all boards would be passed. No call was sent.

Next: ask the custodian to raise the ceiling in the web app (`ceiling_link`).

### CONNECTION_PREVIEW_STALE

HTTP 409. The preview expired (after 10 minutes), its `preview_sha256` does not match, or something it showed changed (the attachment, the definition, a limit or the chosen file).

Next: `request_connection` action `preview` again, show it, then `create` with the new `preview_id` and `preview_sha256`.

### CONNECTION_PENDING

HTTP 409. A call is still running on this card, so a new instruction, answer or revision waits.

Next: wait for it (`manage_connection_request` `list`) or cancel it.

### CONNECTION_ALREADY_DONE

HTTP 409. This card already has that result from this round, and no person asked for changes since.

Next: attach the file that was made instead of asking again.

### CONNECTION_ONE_REQUEST

An agent's reply held more than one `bakedbrie-connection-request` block. Nothing was sent.

Next: the agent asks for one call per reply.

### CONNECTION_REQUEST_INVALID

An agent's `bakedbrie-connection-request` block was not valid JSON or had unknown fields. Nothing was sent.

Next: the agent writes the block exactly as its instructions show.

### CONNECTION_REQUEST_WITH_OUTPUTS

An agent's reply held a request and a `bakedbrie-outputs` block. Nothing was sent and no image was made.

Next: ask for the call alone; make other files after the result comes back.

### CONNECTION_REQUEST_WITH_ATTACH

An agent's reply held a request and a `bakedbrie-attach` block. Nothing was sent.

Next: ask for the call, or finish the work with the attach block, not both.

### CONNECTION_CHECKER_CANNOT_REQUEST

A checker asked for a call. The block was removed and the check went on. Only makers may ask.

Next: nothing; move the request to the maker's instructions.

### CONNECTION_STEP_STAGE_HAS_AGENT

HTTP 409. A column can have an active agent rule or a connection step, not both.

Next: put the step on its own column before the agent's column, and move the card on with `then_stage_id`.

### CONNECTION_STEP_ENTRY_COLUMN

HTTP 422. A step cannot sit on the board's first column: new cards from Slack and schedules start there.

Next: put the step on a later column.

### CONNECTION_SEND_AGAIN_CONFIRM

HTTP 422. Send again was asked for without confirming that it may charge twice. Send again is web only.

Next: the person uses Send again on the card in the web app.

### CONNECTION_CHECK_AGAIN_USED

HTTP 409. Check again works once per call.

Next: `give_up`, or ask the person to look at the service's own dashboard.

### CONNECTION_NOT_CANCELABLE

HTTP 409. The call has finished or is past the point where it can be canceled.

Next: nothing; read its state.

### CONNECTION_NOT_TIMED_OUT

HTTP 409. `check_again` is only for a call in state `timed_out`.

Next: read its state.

### CONNECTION_NOT_UNKNOWN

HTTP 409. That action is only for a call whose outcome is unclear (state `unknown`).

Next: read its state.

### CONNECTION_NOTHING_TO_CONTINUE

HTTP 409. There is no agent to continue for this call (it already continued, or no agent works on the card's column).

Next: nothing to do.

### AGENT_NOT_ON_BOARD

HTTP 422. An id in `agent_ids` is not an agent of this board.

Next: use agents from this board (`manage_agent` `list`).

### STAGE_NOT_ON_BOARD

HTTP 422. A column id (`stage_ids`, `when_stage_id` or `then_stage_id`) is not a column of this board.

Next: read the board's columns (`read_board`) and use those ids.

### EGRESS_DENIED

HTTP 422. The `base_url` or an output host is a private, reserved or BakedBrie address, which BakedBrie never sends to.

Next: use the service's public https address.

### Codes on a connection call

A call that did not end well carries one of these in `code` (with a plain `message`). They are states of the call, not refusals of your tool call. `counted` means the call counts toward the limits at its most it can cost.

| Code | Meaning | Next |
|---|---|---|
| `CONNECTION_NOT_SENT` | BakedBrie could not reach the service. Nothing was sent, nothing counted. | Try again later. |
| `CONNECTION_PROVIDER_REFUSED` | The service refused the call (for example bad input). Nothing counted. | Fix the inputs, then ask again. |
| `CONNECTION_KEY_REJECTED` | The service did not accept the key. Nothing counted. | `manage_connection` `replace_key`, then try again. |
| `CONNECTION_KEY_INVALID` | The saved key has characters a header cannot carry. | `replace_key`. |
| `CONNECTION_KEY_UNAVAILABLE` | The saved key is gone. | `replace_key`. |
| `CONNECTION_PROVIDER_BUSY` | The service was too busy to take the call, after retries. Nothing counted. | Try again later. |
| `CONNECTION_PROVIDER_LOCKED` | The service says the account is locked or out of balance. Nothing counted. | The person fixes it at the service, then tries again. |
| `CONNECTION_OUTCOME_UNKNOWN` | The call was sent but no answer came back. It may have been accepted. Counted, state `unknown`, never sent again by BakedBrie. | The person checks their account at the service. Send again (may charge twice) is web only; or `give_up`. |
| `CONNECTION_ANSWER_UNCLEAR` | The service answered, but not in the expected form (for example no job id). It may have accepted. Counted, state `unknown`. | Same as `CONNECTION_OUTCOME_UNKNOWN`; check the definition's `job_id` path. |
| `CONNECTION_PROVIDER_FAILED` | The service could not make the result. | Try again with other inputs, or finish without it. |
| `CONNECTION_JOB_NOT_FOUND` | The service no longer knows the job. | Ask again if needed. |
| `CONNECTION_TIMED_OUT` | Not finished within `poll.max_wait_s`. Counted. | `check_again` once, or `give_up`. |
| `CONNECTION_OUTPUT_HOST_NOT_ALLOWED` | The file link is on a host the connection's `output_hosts` does not list. Counted, nothing saved. | If you trust that host, add it (exact) to `output_hosts`. |
| `CONNECTION_OUTPUT_TYPE` | The file was not one of the output's `media_types`. Counted. | Check the operation's outputs. |
| `CONNECTION_OUTPUT_TOO_LARGE` | The file is larger than the output's `max_bytes`. Counted. | Raise `max_bytes` (up to 45 MB) or ask for a smaller result. |
| `CONNECTION_OUTPUT_EXPIRED` | The file link expired before BakedBrie could save it. Counted. | Ask again; check `output_ttl_s`. |
| `CONNECTION_STORAGE_FULL` | The workspace's storage is full. Counted. | Free space, then ask again. |
| `CONNECTION_INPUT_CHANGED` | The chosen card file changed after it was chosen. Not sent. | Choose it again. |
| `CONNECTION_CHANGED` | The connection's definition or key changed after the request was made. Not sent. | Make the request again. |
| `CONNECTION_OPERATION_REMOVED` | The operation was removed from the board. Not sent. | Nothing, or add it back. |
| `CONNECTION_REQUEST_STALE` | It waited more than a day and was not sent. | Make it again if still needed. |
| `CONNECTION_CANCELED_BEFORE_SEND` | Canceled before it was sent. Nothing counted. | Nothing. |
| `CONNECTION_CANCELED` | Canceled after it was sent. The service may still charge for work it started. | Nothing. |
| `CONNECTION_CONTINUE_CARD_MOVED` | The file is saved, but the card moved, so the agent was not asked to continue. | `manage_connection_request` `continue` if it should. |
| `CONNECTION_CONTINUE_BUSY` | The file is saved; someone else is working on the card. | `continue` when the card is free. |
| `CONNECTION_CONTINUE_REVIEW_PENDING` | The file is saved; a review is waiting on the card. | Decide the review first. |
| `CONNECTION_LOOP_GUARD` | The agent asked for calls three times in this round. | A person decides what happens next. |
| `CONNECTION_CONTINUE_ROUNDS` | The card reached its limit of rounds. | A person decides what happens next. |
| `WORK_FOLDER_REQUIRED` | The board has no work folder, so the file would have nowhere to go. Not sent. | Set a work folder (`set_work_folder`). |

## Inbound endpoints and Slack links

These need the `inbound` and `api_workflow` capabilities.

### SIGNING_SECRET_IN_USE

HTTP 409. Another endpoint already uses this signing secret. Each endpoint needs its own Slack app or secret.

Next: use a different secret for this endpoint.

### MAPPING_CONFLICT

HTTP 409. The Slack user was linked at the same moment by someone else.

Next: `manage_member_mapping` `list`, then decide with the user.

### MEMBER_UNAVAILABLE

HTTP 422. A Slack user can only be linked to an active member of this workspace.

Next: pick an active member (`user_id`).

## Runner key and run codes

Only `bakedbrie-runner` uses the runner routes. You see these codes on cards, in `list_ai_accounts`, or when helping the user with the runner. Full contract: `docs/runner-protocol.md`.

### RUNNER_TOKEN_REQUIRED

HTTP 403. The runner routes accept a runner key only. Next: mint a runner key ([Tokens and the runner](/docs/tokens-and-runner)).

### RUNNER_TOKEN_INVALID

HTTP 403. The key is not a runner key. Next: same as above.

### RUNNER_TOKEN_FORBIDDEN

HTTP 403. A runner key cannot change this. Next: use a normal token.

### RUNNER_DEVICE_UNAVAILABLE

HTTP 403. This computer was disconnected, or the device belongs to another key. Next: create a new runner key and run `bakedbrie-runner pair`.

### RUNNER_MEMBER_INELIGIBLE

HTTP 403. The key's member cannot run cards in this workspace (viewers cannot). Next: a member with work permission creates the key.

### WORKSPACE_MISMATCH

HTTP 403. The runner key belongs to another workspace. Next: pair with a key from this workspace.

### UPLOADS_OFF

HTTP 409. Output file uploads are off; the files stay on the computer and the run still completes. Next: nothing; the files are named in the result.

### UPLOAD_UNKNOWN

HTTP 422. A finished run named an upload this computer did not prepare. The runner sends the answer again without it.

### Run codes on a card

| Code | Meaning | Next |
|---|---|---|
| `RUNTIME_SIGNED_OUT` | `claude` or `codex` is signed out | The user signs in to their plan |
| `RUNTIME_OUTDATED` | Older than claude 2.1.280 or codex-cli 0.155.1 | The user updates it |
| `RUNTIME_MISSING` | The program is not on PATH | The user installs it |
| `RUNTIME_API_BILLING` | Signed in with an API key, not a plan | Sign in with the plan, or start the runner with `--allow-api-billing` |
| `RUNTIME_UNSAFE_CONFIG` | The program showed tools or settings the runner does not allow, or a work folder is a symbolic link | Remove the link or extra configuration |
| `RUNTIME_TIMEOUT` | The run hit the 15-minute limit | Split the card into smaller work |
| `RUNTIME_ERROR` | The program failed | Check the card's activity; try again |
| `RUNNER_STOPPED` | The runner was stopped during the run | Start `bakedbrie-runner` again; the card can run again |
| `RUNNER_PROVIDER_OFF` | BakedBrie turned off this program for runners | Wait, or bind another AI account |
| `LEASE_LOST`, `RUN_ALREADY_FINISHED` | The run was taken back or already finished | Nothing; the answer is final |

## OAuth connections and webhooks

### CONNECTION_OAUTH_NOT_CONNECTED

HTTP 409. {connection} is not signed in yet. A person needs to sign in to {service} in BakedBrie first.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_SIGN_IN_NEEDED

HTTP 409. Sign in to {service} again. Calls to {connection} wait until a person signs in.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_ACCOUNT_CHANGED

Status code. {connection} is now signed in to a different {service} account than this call was made for. No call was sent.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_WRITE_TAINTED

HTTP 409. Data from a connected service on this card includes free text, so BakedBrie allows only reads until a person starts a new round. No change was made.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_WEBHOOK_CARD_READ_ONLY

HTTP 409. This card came from a {connection} event, and its rule does not allow changes. Only reads are allowed.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_EMAIL_ENDPOINT_REFUSED

Status code. BakedBrie never sends email through a connection. This path of {service} sends email, so it is not allowed.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_ANSWER_TOO_LARGE

Status code. {connection} answered with more data than BakedBrie keeps (256 KB, or 16 KB after picking fields). Ask for fewer items.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_ANSWER_UNREADABLE

Status code. {connection} answered, but not with the data this operation expects.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_READ_METHOD

HTTP 422. A read must use GET. Mark this operation as a write, or use GET.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_QUERY_INPUT_NEEDS_PATTERN

HTTP 422. {input} goes into a query, so it needs a pattern (such as digits or doc_number) that keeps quotes out.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_NO_ACCOUNT

Status code. {service} did not list any account this sign-in can use. Sign in with a user who has access to the company, then try again.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_ACCOUNT_CHOICE_EXPIRED

HTTP 409. The choice of account expired after 30 minutes. Sign in to {service} again.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_ACCOUNT_PARAM_INVALID

HTTP 422. {service} sent back an account value BakedBrie cannot use. Sign in again.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_TYPED_VALUE_INVALID

HTTP 422. {label} is not valid. Use only letters, digits and dashes (or a UUID where one is asked for), with no dots, @ or %.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_TYPED_HOST_NOT_ALLOWED

HTTP 422. {label} points to a host this connection does not allow. Check the value, or the connection's allowed hosts.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_PREPARE_EXPIRED

HTTP 409. This sign-in link expired or was already used. Start signing in again.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_SCOPE_WIDER_THAN_REQUESTED

Status code. {service} granted more access than BakedBrie asked for, so BakedBrie did not keep the sign-in. Remove unused API permissions from your {service} app registration, then sign in again.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_SCOPE_WIDER_THAN_OPERATIONS

HTTP 422. {connection} asks for more access than its operations need. Remove {scopes}, or add the operation that needs it.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_MESSAGE_ENDPOINT_REFUSED

HTTP 422. BakedBrie never posts messages or sends invites through a connection. This path of {service} reaches people, so it is not allowed. Use a Teams destination for approved messages.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CLIENT_SECRET_EXPIRING

Status code. The client secret for {connection} expires on {date}. Make a new secret in your {service} app and paste it in BakedBrie before then.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### TEAMS_MESSAGE_TOO_LONG

HTTP 409. This message is longer than Teams allows (20,000 bytes). Request changes to shorten it.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### TEAMS_MESSAGE_NOT_APPROVED

Status code. This Teams message was not approved by a person exactly as written, so BakedBrie did not post it.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### TEAMS_MESSAGE_INVALID

Status code. This Teams message is empty, so there is nothing to post. Request changes to write the message.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### TEAMS_OUTCOME_UNKNOWN

Status code. Teams may have posted this message. Check the channel before sending again.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### TEAMS_PATH_REFUSED

Status code. The Teams destination can only post to its one channel.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OUTLOOK_PATH_REFUSED

Status code. The Outlook draft destination can only create drafts. BakedBrie never sends email.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### EMAIL_BLOCK_REQUIRED

HTTP 409. This card's work goes to {Mail} Drafts, so the result must end with one bakedbrie-email block.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### EMAIL_RECIPIENT_UNVERIFIED

HTTP 409. The email's recipient must be an address from a customer or contact read on this card in this round.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### EMAIL_HEADER_INVALID

HTTP 409. The email's recipient or subject is not valid. Use one address and a one-line subject.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### GMAIL_PATH_REFUSED

HTTP 422. A Gmail draft destination can only create drafts. BakedBrie never sends email.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_SIGNATURE_INVALID

HTTP 401. The webhook signature is missing or wrong. Check the signing secret in BakedBrie.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_EVENT_STALE

Status code. This event was more than 72 hours old, or dated in the future, so it made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_FLOOD_PAUSED

Status code. {connection} reached its daily limit of {n} cards from events. New events make no cards until tomorrow (UTC) or until a person raises the limit.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_RULE_NEEDS_LIMITS

Status code. Set the limits for {connection} on {board} before events can make cards.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_SECRET_WEB_ONLY

HTTP 403. Only a person can paste the signing secret, in the BakedBrie web app.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_WRITES_WEB_ONLY

HTTP 403. Only a person in the BakedBrie web app can let cards from events change records.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_PROVIDER_UNSUPPORTED

HTTP 422. Webhooks work only with the QuickBooks Online and Xero connections.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_EXISTS

HTTP 409. {connection} already has a webhook.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_RULE_STAGE_INVALID

HTTP 422. Choose a column on this board that has no connection step.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_TEMPLATE_INVALID

HTTP 422. Card titles and briefs from events can use only {{event.entity}}, {{event.id}} and {{event.operation}}.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### CONNECTION_WEBHOOK_NOT_FOUND

HTTP 404. This webhook is unavailable.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_RULE_NOT_FOUND

HTTP 404. This webhook rule is unavailable.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_BODY_TOO_LARGE

HTTP 413. The webhook body is larger than 1 MB.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_EVENT_INVALID

Status code. This event could not be read, so it made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_ACCOUNT_NOT_HELD

Status code. This event is for a {service} account this connection is not signed in to, so it made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_PAUSED

Status code. The webhook was paused, so this event made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_OWNER_UNAVAILABLE

Status code. The person who made this rule can no longer create cards on this board, so the event made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_BOARD_UNAVAILABLE

Status code. The board is archived, so the event made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_EVENT_FAILED

Status code. BakedBrie could not process this event after 5 tries, so it made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_SECRET_NEEDED

HTTP 409. Paste the signing secret in BakedBrie before turning the webhook on.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_ECHO

Status code. BakedBrie made this change itself a moment ago, so the event made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### WEBHOOK_NO_RULE

Status code. No rule on any board uses this kind of event, so it made no card.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_REVOKE_TIMEOUT

Status code. BakedBrie deleted its copy of the sign-in, but {service} did not confirm the revoke in time. Remove the app's access in {service} if you want to be sure.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

### OAUTH_REVOKE_UNFINISHED

Status code. BakedBrie is still revoking sign-ins for this workspace and will try again shortly.

Next: follow the message; change the setup or ask the named person to use the BakedBrie web app when it says the step is web only.

<!--
Built from: DomainError and toolError codes in apps/api/src/server.ts (token door, headers), apps/api/src/mcp/server.ts and apps/api/src/mcp/v21/*.ts (MCP, fix hints), apps/api/src/v21/*.ts (V2.1 routes, presets, runner, media), packages/domain/src/index.ts and packages/domain/src/lanes/board/*.ts (base board and card commands), packages/domain/src/v21/*.ts (control, destinations, reviews, secrets, inbound, identities, google, connections), packages/contracts/src/v21/connections.ts (connection codes), apps/api/src/workspace-rate.ts, packages/db/src/index.ts, docs/runner-protocol.md, apps/runner/README.md.
Left out on purpose: codes only a browser session can reach (session, CSRF, invitations, marketplace, migrations), and codes only an inbound webhook sender sees (signature and mapping codes).
-->
