When a call fails

Check the status, then read the shape that goes with it.

Four shapes

Shape You get it for
{"error": {"code": …, "message": …}} A refusal with a name. 404, 422, 502. code is the one thing safe to branch on
{"error": "<message>"} Something not built yet. 501
{"detail": "<message>"} You were stopped before the call got in. 401, 403, 405, 429
{"<field>": ["<reason>"]} Your body or query string could not be read. 400

A 422 about a diagram carries violations as well, listing what is wrong and which block it is about.

The statuses

  • 400 — we could not read what you sent. Keyed by the field at fault, or non_field_errors when no single field is.
  • 401 — no credentials, or credentials that name nobody.
  • 403 — you are signed in and may not do this. Three different things answer this and the body does not say which: your role lacks the permission; the brand is disabled or locked; the subscription has expired and you tried to write.
  • 404 — no such bot, or not yours. The two answer identically. A connected account answers the same way, and one that was revoked, or that the app asks to reconnect, answers as if it were not there.
  • 405 — the path exists, the method does not.
  • 422 — we understood you and refused. Either a value we do not accept, or a diagram that breaks rules.
  • 429 — too many requests. Every call counts, reads included.
  • 501 — described here, not built yet.
  • 502 — something we depend on failed. Retrying is reasonable.

Refusals that carry a code

bot_not_found · version_not_found · block_not_found · workspace_not_found · bot_name_not_accepted · channel_family_not_readable · bot_not_in_the_trash · builder_version_not_supported · diagram_beside_a_source · draft_has_violations · restored_draft_has_violations · version_of_an_unsupported_builder · version_is_the_most_recent_publication · diagram_compilation_failed · connected_account_not_found · google_spreadsheets_failed

Rules a diagram can break

Each one is a code in a violation. A code you get that is not listed here came from a bot an older builder wrote, and is passed through rather than invented.

Refused on the spot

These answer 422 and store nothing, because there would be nothing sensible to store.

  • block_unknown — the block is of a type we do not describe.
  • block_id_taken — the id you gave a new block already names one in the diagram.
  • block_not_in_draft — you named a block for update or delete that the draft does not hold. Only PATCH /bots/{bot_id}/draft reports it; the single-block endpoints answer 404.
  • block_params_undescribed — the params leave us unable to say which block it is.
  • param_output_id_invalid — something you derive an output from has an id that cannot be one: a button payload not starting with $. Names it in param.
  • param_formula_not_compiled — the formula does not compile.
  • connection_output_removed — your change takes away an output a connection still leaves from. Names those connections in connections.
  • connection_block_removed — you added a connection to a block the same change set deletes.

Stored, and reported back

Everything below is saved with your draft. You keep editing; you cannot publish or test until they are gone.

Two of them cut both ways. entry_node_of_another_channel and connection_output_unknown are stored when a whole-diagram write puts them there, and refused on the spot when you add or edit the block that causes them — POST /bots/{bot_id}/draft/blocks is where an id is chosen, and the block-level writes are where an output is.

The block the bot starts from

  • start_connection — the diagram holds neither the greeting node nor the start point.
  • welcome_block_not_allowed — the block in the greeting slot cannot be a greeting. can_be_welcome in GET /blocks says which can.
  • welcome_version_invalid — the greeting does not carry version: 3. landbot bots only. We add the marker when you add the block, so what is left to report is a version you sent yourself, and PUT /bots/{bot_id}/draft, which stores the diagram as it is sent.
  • entry_node_of_another_channel — a node uses another channel family's greeting id: welcome on a bot that is not landbot, or bot_start on one that is. Refused on the spot when you add the block.

Wiring

  • connection_wrong — a connection has an end the diagram does not contain.
  • connection_output_unknown — a connection leaves from an output its block does not have. Refused on the spot when you add or edit that block.
  • bot_loop — blocks that never wait for an answer form a closed loop, so the conversation never reaches the person.
  • brick_level — bricks nested deeper than allowed.

One param, named in param

  • param_required — missing.
  • param_invalid_type — wrong type.
  • param_no_matching_shape — matches none of the shapes declared for it. GET /blocks has them.
  • param_non_empty — empty where it may not be.
  • param_invalid_format — does not match the pattern in GET /blocks.
  • param_forbidden_format — matches a pattern it must not.
  • param_too_long — longer than max_length.
  • param_not_allowed — not one of the enum values.
  • param_reserved — a value the block keeps for itself.
  • param_unknown_function — a formula calls a function the block does not know.
  • param_invalid_json — has to be JSON and does not parse.

About storage rather than the diagram

  • block_is_not_valid — a violation was stored against the block with no readable code. Something is wrong with it; what, we cannot recover.