Reference
Error reference
Every error code BrowserHive can produce (98 codes), generated from ERROR_REGISTRY in @browserhive/contracts/errors. Each code has a stable anchor: errors.md#<CODE>, which is also the type URL of HTTP problem responses (https://browserhive.ai/docs/errors#<CODE>).
How errors reach you
Section titled “How errors reach you”- MCP tools: the result has
isError: trueand a text block[CODE] message(a stable text format clients may parse). The structured form{ code, message, retryable, hint?, details? }is in_meta["browserhive.ai/error"]. - REST API:
application/problem+json(RFC 9457) withtype,title,status,detail, pluscode,retryable,hint,detailsandrequest_id. - WebSocket: a frame with
kind: "error"and payload{ code, title, hint?, details?, request_id? }; thecorrof the failed command is echoed. - CLI: boot errors print
browserhive: [CODE] messageto stderr and exit with the code listed per entry.
Retry guidance
Section titled “Retry guidance”retryable |
Meaning |
|---|---|
never |
do not retry; the request cannot succeed as sent |
immediate |
safe to retry right away |
backoff |
retry later with backoff |
after_operator |
retry after an operator acts (unlock the vault, resolve a request, change policy) |
different_args |
retry only with different arguments |
Domain errors
Section titled “Domain errors”Returned by tools and the REST API when a request cannot be served (unknown session, blocked URL, vault locked…).
| Code | Title | HTTP | Retryable |
|---|---|---|---|
SESSION_NOT_FOUND |
Session not found | 404 | different_args |
SESSION_ALREADY_EXISTS |
Session id collision | 409 | immediate |
SESSION_DEAD |
Session is dead | 410 | different_args |
SESSION_LIMIT_REACHED |
Session limit reached | 429 | backoff |
SESSION_ACCESS_DENIED |
Session not found | 404 | never |
SESSION_NOT_AVAILABLE |
Session not available | 409 | after_operator |
SESSION_NOT_LIVE |
Session is not live | 409 | never |
SESSION_LIVE |
Session is still live | 409 | never |
UNKNOWN_CHANNEL |
Unknown browser channel | 400 | different_args |
INVALID_SLUG |
Invalid slug | 400 | different_args |
UNSAFE_LAUNCH_ARG |
Launch argument denied | 400 | different_args |
INVALID_PERSISTENCE_CONFIG |
Invalid persistence config | 400 | different_args |
TAB_NOT_FOUND |
Tab not found | 404 | different_args |
PATH_NOT_ALLOWED |
Path outside the sandbox | 400 | different_args |
AUTH_STATE_NOT_FOUND |
Saved auth state not found | 404 | different_args |
EVALUATE_DISABLED |
evaluate is disabled | 403 | never |
ELEMENT_NOT_ACTIONABLE |
Element not actionable | 422 | backoff |
ELEMENT_NOT_FOUND |
Element not found | 404 | different_args |
NAVIGATION_TIMEOUT |
Navigation timed out | 504 | backoff |
NAVIGATION_FAILED |
Navigation failed | 502 | backoff |
WAIT_TIMEOUT |
Wait timed out | 504 | backoff |
SCRIPT_ERROR |
Script threw | 422 | different_args |
DOWNLOAD_FAILED |
Download failed | 502 | backoff |
UPLOAD_FAILED |
Upload failed | 422 | different_args |
PAGE_CLOSED |
Page closed | 410 | different_args |
BROWSER_CRASHED |
Browser crashed | 500 | after_operator |
URL_BLOCKED |
URL blocked by policy | 403 | never |
BROWSER_NOT_INSTALLED |
Browser not installed | 503 | after_operator |
VAULT_NOT_CONFIGURED |
No vault configured | 404 | never |
VAULT_LOCKED |
Vault locked | 409 | after_operator |
VAULT_ENTRY_NOT_FOUND |
Vault entry not found | 404 | different_args |
VAULT_NOT_AUTHORIZED |
Vault entry not authorized | 403 | never |
EVALUATE_REQUIRED_OFF |
Entry requires evaluate disabled | 403 | never |
DASHBOARD_DENIED |
Fill denied by operator | 403 | after_operator |
VAULT_UNLOCK_FAILED |
Vault unlock failed | 401 | different_args |
VAULT_SYNC_UNSUPPORTED |
Vault sync unsupported | 400 | never |
VAULT_BACKEND_ERROR |
Vault backend error | 502 | backoff |
ATTENTION_REQUIRES_HTTP |
Attention requires http | 400 | never |
ATTENTION_NOT_OPEN |
Attention request is not open | 409 | never |
CONFIRM_NOT_OPEN |
Confirmation is not open | 409 | never |
INPUT_NOT_PERMITTED |
Input not permitted | 409 | after_operator |
SCREENCAST_FAILED |
Screencast failed | 502 | backoff |
TOOL_NOT_AVAILABLE |
Tool not available | 400 | never |
INVALID_ARGUMENTS |
Invalid arguments | 400 | different_args |
TRACE_UNAVAILABLE |
Trace unavailable | 404 | never |
SCREENSHOT_UNAVAILABLE |
Screenshot unavailable | 404 | never |
INTERNAL_ERROR |
Internal error | 500 | backoff |
SESSION_NOT_FOUND
Section titled “SESSION_NOT_FOUND”| Property | Value |
|---|---|
| Title | Session not found |
| HTTP status | 404 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: No browser session with id '{session_id}'
Hint: Use list_sessions to see live sessions.
Cause: The session id is unknown, mistyped, or the session was already closed and removed.
Resolution: Call list_sessions and use one of the returned ids, or launch a new session.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
SESSION_ALREADY_EXISTS
Section titled “SESSION_ALREADY_EXISTS”| Property | Value |
|---|---|
| Title | Session id collision |
| HTTP status | 409 |
| Category | domain |
| Retryable | immediate (safe to retry right away) |
Message: Session '{session_id}' already exists. Slug+nanoid collision is exceptionally rare; the caller should retry.
Hint: Retry launch_session; a fresh id is generated on every call.
Cause: The generated <slug>-<nanoid8> id collided with a live session (36^8 space).
Resolution: Retry immediately; a collision twice in a row indicates a broken id generator.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
SESSION_DEAD
Section titled “SESSION_DEAD”| Property | Value |
|---|---|
| Title | Session is dead |
| HTTP status | 410 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Session '{session_id}' is dead — its underlying browser process crashed.
Hint: Close the session and launch a new one.
Cause: The browser context or process disconnected; the session is awaiting reaping.
Resolution: Launch a replacement session; the crashed one is closed with reason crash.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
SESSION_LIMIT_REACHED
Section titled “SESSION_LIMIT_REACHED”| Property | Value |
|---|---|
| Title | Session limit reached |
| HTTP status | 429 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Concurrent session limit reached (max={limit}). Close a session and retry.
Hint: Close an idle session or wait for a lease to expire, then retry.
Cause: The number of live sessions equals maxSessions (derived from host RAM by default).
Resolution: Close sessions you no longer need, or raise maxSessions on a host with more memory.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
limit |
integer |
yes | — |
live |
integer |
yes | — |
SESSION_ACCESS_DENIED
Section titled “SESSION_ACCESS_DENIED”| Property | Value |
|---|---|
| Title | Session not found |
| HTTP status | 404 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: No browser session with id '{session_id}'
Hint: Use list_sessions to see the sessions you own.
Cause: The session belongs to a different principal and ownership enforcement is on (auth=token).
Resolution: Only the owning principal may use a session; launch your own.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
SESSION_NOT_AVAILABLE
Section titled “SESSION_NOT_AVAILABLE”| Property | Value |
|---|---|
| Title | Session not available |
| HTTP status | 409 |
| Category | domain |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: Session '{session_id}' is not available (state: {state}).
Hint: Wait until the session is live, or pick another session.
Cause: The session is launching, draining, paused for an operator, closed or crashed.
Resolution: Retry once the session state returns to live.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
state |
string |
yes | — |
SESSION_NOT_LIVE
Section titled “SESSION_NOT_LIVE”| Property | Value |
|---|---|
| Title | Session is not live |
| HTTP status | 409 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Session '{session_id}' is not live.
Hint: This action needs a live session; the session has ended.
Cause: An operator action that needs a running browser (live view, input, terminate) targeted a closed session.
Resolution: Open the trace or history views instead.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
SESSION_LIVE
Section titled “SESSION_LIVE”| Property | Value |
|---|---|
| Title | Session is still live |
| HTTP status | 409 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Session '{session_id}' is still live.
Hint: Terminate or close the session first.
Cause: An action that needs a finished session (archive, delete, trace download) targeted a live one.
Resolution: Close the session, then retry.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
UNKNOWN_CHANNEL
Section titled “UNKNOWN_CHANNEL”| Property | Value |
|---|---|
| Title | Unknown browser channel |
| HTTP status | 400 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Unknown browser channel '{channel}'. Expected one of: chromium, chrome, edge.
Hint: Pass channel as one of chromium, chrome or edge.
Cause: The channel argument is not a supported Chromium-family channel.
Resolution: Use chromium (bundled), or chrome/edge when that browser is installed on the host.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
channel |
string |
yes | — |
supported |
string[] |
yes | — |
INVALID_SLUG
Section titled “INVALID_SLUG”| Property | Value |
|---|---|
| Title | Invalid slug |
| HTTP status | 400 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Invalid slug '{slug}'. Slugs must match /^[a-z][a-z0-9-]{1,31}$/ (start with a lowercase letter, 2–32 chars, lowercase alphanumerics and dashes).
Hint: Use a short lowercase name such as “shop” or “docs-crawl”.
Cause: The slug does not match the filesystem-safe grammar.
Resolution: Lowercase letters, digits and dashes only; start with a letter; 2–32 characters.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
slug |
string |
yes | — |
pattern |
string |
yes | — |
UNSAFE_LAUNCH_ARG
Section titled “UNSAFE_LAUNCH_ARG”| Property | Value |
|---|---|
| Title | Launch argument denied |
| HTTP status | 400 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Launch arg '{arg}' is on the deny-list and would break session isolation.
Hint: Remove the argument from launch_options.args.
Cause: A Chromium flag that changes the profile directory, sandbox or debugging surface was passed.
Resolution: Use the persistence modes and channel options instead of raw isolation-breaking flags.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
arg |
string |
yes | — |
INVALID_PERSISTENCE_CONFIG
Section titled “INVALID_PERSISTENCE_CONFIG”| Property | Value |
|---|---|
| Title | Invalid persistence config |
| HTTP status | 400 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Invalid persistence config: {reason}
Hint: Check the persistence_mode / restore_profile / storage_state / incognito combination.
Cause: The requested combination of persistence mode and launch options is contradictory.
Resolution: See the persistence matrix in the tool reference and pick a consistent combination.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
reason |
string |
yes | — |
TAB_NOT_FOUND
Section titled “TAB_NOT_FOUND”| Property | Value |
|---|---|
| Title | Tab not found |
| HTTP status | 404 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Tab '{tab_id}' not found in session '{session_id}'.
Hint: Use list_tabs to see open tabs.
Cause: The tab id is unknown or the tab was closed; <active> means the session has no open tab.
Resolution: Call list_tabs, or open a tab with new_tab.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
tab_id |
string |
yes | — |
PATH_NOT_ALLOWED
Section titled “PATH_NOT_ALLOWED”| Property | Value |
|---|---|
| Title | Path outside the sandbox |
| HTTP status | 400 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Path '{path}' is outside the allowed sandbox roots.
Hint: Use a relative path or an absolute path under an allowed root.
Cause: The resolved path (symlinks followed) escapes the session directory and the uploads directory.
Resolution: Write inside the session directory (relative paths resolve there) or the uploads directory.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
path |
string |
yes | — |
roots |
string[] |
yes | — |
AUTH_STATE_NOT_FOUND
Section titled “AUTH_STATE_NOT_FOUND”| Property | Value |
|---|---|
| Title | Saved auth state not found |
| HTTP status | 404 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: No saved {kind_label} snapshot named '{name}'. Use list_saved_auths to see what is available.
Hint: Call list_saved_auths and use one of the returned names.
Cause: No snapshot of the requested kind exists under that name in the auth-states directory.
Resolution: Save one with save_storage_state or save_full_profile first.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
name |
string |
yes | — |
kind |
one of storage, profile |
yes | — |
EVALUATE_DISABLED
Section titled “EVALUATE_DISABLED”| Property | Value |
|---|---|
| Title | evaluate is disabled |
| HTTP status | 403 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The 'evaluate' tool is disabled for session '{session_id}'.
Hint: Use the structured tools (click, fill, get_content, snapshot) instead.
Cause: The session was launched with disable_evaluate: true, or the server runs with allowEvaluate=false.
Resolution: Relaunch without disable_evaluate, or ask the operator to enable allowEvaluate.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
scope |
one of session, server |
yes | — |
ELEMENT_NOT_ACTIONABLE
Section titled “ELEMENT_NOT_ACTIONABLE”| Property | Value |
|---|---|
| Title | Element not actionable |
| HTTP status | 422 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Element '{selector}' did not become actionable within the timeout — it may be hidden, detached, disabled, covered by another element, or the selector matched the wrong element. Use a more specific, visible selector, or raise the timeout.
Hint: Take a snapshot to find a visible, unique selector; raise timeout_ms if the page is slow.
Cause: The target was hidden, detached, disabled, covered, or the selector matched the wrong element.
Resolution: Use a more specific selector or wait for the element to become visible first.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
selector |
string |
yes | — |
detail |
string |
no | — |
ELEMENT_NOT_FOUND
Section titled “ELEMENT_NOT_FOUND”| Property | Value |
|---|---|
| Title | Element not found |
| HTTP status | 404 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: No element matched selector '{selector}'.
Hint: Take a snapshot and pick a selector that matches exactly one element.
Cause: The selector matched nothing, or matched several elements under strict mode.
Resolution: Refine the selector; count in details tells you how many matched.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
selector |
string |
yes | — |
count |
integer |
no | — |
NAVIGATION_TIMEOUT
Section titled “NAVIGATION_TIMEOUT”| Property | Value |
|---|---|
| Title | Navigation timed out |
| HTTP status | 504 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Navigation to '{url}' did not finish within {timeout_ms} ms.
Hint: Retry with a longer timeout_ms or a lighter wait_until (commit, domcontentloaded).
Cause: The page did not reach the requested load state before the timeout.
Resolution: Raise the timeout, choose an earlier wait_until, or check the network.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
url |
string |
yes | — |
timeout_ms |
integer |
yes | — |
NAVIGATION_FAILED
Section titled “NAVIGATION_FAILED”| Property | Value |
|---|---|
| Title | Navigation failed |
| HTTP status | 502 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Navigation to '{url}' failed ({net_error}).
Hint: Check the URL and network; net_error names the Chromium failure.
Cause: Chromium reported a network error (net::ERR_*): DNS, TLS, connection refused, and so on.
Resolution: Verify the URL resolves and is reachable from the host; retry transient failures.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
url |
string |
yes | — |
net_error |
string |
yes | — |
WAIT_TIMEOUT
Section titled “WAIT_TIMEOUT”| Property | Value |
|---|---|
| Title | Wait timed out |
| HTTP status | 504 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Timed out after {timeout_ms} ms waiting for {what}.
Hint: Raise timeout_ms or wait for a different condition.
Cause: The awaited selector state, URL or load state did not occur in time.
Resolution: Check the page state with snapshot, then wait for a condition that will happen.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
what |
string |
yes | — |
timeout_ms |
integer |
yes | — |
SCRIPT_ERROR
Section titled “SCRIPT_ERROR”| Property | Value |
|---|---|
| Title | Script threw |
| HTTP status | 422 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: The evaluated script threw: {message}
Hint: Fix the script; the first line of the page error is in details.message.
Cause: The expression passed to evaluate threw inside the page.
Resolution: Correct the script or guard against missing globals.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
message |
string |
yes | — |
DOWNLOAD_FAILED
Section titled “DOWNLOAD_FAILED”| Property | Value |
|---|---|
| Title | Download failed |
| HTTP status | 502 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Download failed: {reason}
Hint: Retry; if it persists, check that the link starts a download.
Cause: The browser reported the download as failed or cancelled.
Resolution: Retry the download; verify the target actually serves a file.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
reason |
string |
yes | — |
UPLOAD_FAILED
Section titled “UPLOAD_FAILED”| Property | Value |
|---|---|
| Title | Upload failed |
| HTTP status | 422 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Upload failed: {reason}
Hint: Check that the selector targets a file input and the file exists under uploads/.
Cause: setInputFiles failed: wrong element, missing file, or a page that rejected the input.
Resolution: Target an <input type=file> and place the file in the uploads directory.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
reason |
string |
yes | — |
PAGE_CLOSED
Section titled “PAGE_CLOSED”| Property | Value |
|---|---|
| Title | Page closed |
| HTTP status | 410 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Tab '{tab_id}' was closed while the action was running.
Hint: Use list_tabs and target an open tab.
Cause: The page or its execution context was destroyed mid-call (closed tab, navigation away).
Resolution: Re-open or re-target the tab and retry.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
tab_id |
string |
yes | — |
BROWSER_CRASHED
Section titled “BROWSER_CRASHED”| Property | Value |
|---|---|
| Title | Browser crashed |
| HTTP status | 500 |
| Category | domain |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: The browser behind session '{session_id}' crashed.
Hint: Launch a new session; the crashed one will be reaped.
Cause: The browser context or process was closed unexpectedly.
Resolution: Launch a replacement session; check host memory if it repeats.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
URL_BLOCKED
Section titled “URL_BLOCKED”| Property | Value |
|---|---|
| Title | URL blocked by policy |
| HTTP status | 403 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The URL '{url}' is blocked by the administrator (matched the blocklist pattern '{pattern}'). This is an operator policy, not a transient failure — do not retry this URL, and do not try to reach it by another route. Report it to the user if the task cannot continue.
Hint: Do not retry; report the block to the user.
Cause: The URL matched a pattern in the operator blocklist (blocklist file).
Resolution: Operators edit the blocklist file (reloaded live) if the block is unintended.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
url |
string |
yes | — |
pattern |
string |
yes | — |
BROWSER_NOT_INSTALLED
Section titled “BROWSER_NOT_INSTALLED”| Property | Value |
|---|---|
| Title | Browser not installed |
| HTTP status | 503 |
| Category | domain |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: No browser is installed for channel '{channel}'. Run '{install_command}' on the host.
Hint: Ask the operator to run browserhive init.
Cause: The Chromium binary for the driver/channel is missing (no postinstall download, D-18).
Resolution: Run browserhive init, or install the branded browser for chrome/edge.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
channel |
string |
yes | — |
install_command |
string |
yes | — |
VAULT_NOT_CONFIGURED
Section titled “VAULT_NOT_CONFIGURED”| Property | Value |
|---|---|
| Title | No vault configured |
| HTTP status | 404 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: No vault backend is configured. Start the server with --vault <backend>.
Hint: Ask the operator to start the server with vault=bitwarden.
Cause: The server runs with vault=off.
Resolution: Start with --vault bitwarden and unlock it.
Details: none.
VAULT_LOCKED
Section titled “VAULT_LOCKED”| Property | Value |
|---|---|
| Title | Vault locked |
| HTTP status | 409 |
| Category | domain |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: Vault backend is locked. Unlock it on the dashboard Vault page.
Hint: Ask the operator to unlock the vault, then retry.
Cause: The backend session token is absent or expired.
Resolution: Run bw unlock --raw and paste the session token on the dashboard Vault page, or restart the server with BW_SESSION exported.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
backend |
string |
yes | — |
VAULT_ENTRY_NOT_FOUND
Section titled “VAULT_ENTRY_NOT_FOUND”| Property | Value |
|---|---|
| Title | Vault entry not found |
| HTTP status | 404 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Vault entry '{entry_name}' is not in the backend.
Hint: Use vault_list_available to see entries you may fill.
Cause: No binding or backend item matches the requested entry name.
Resolution: Pick a name from vault_list_available, or ask the operator to bind the item.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
entry_name |
string |
yes | — |
VAULT_NOT_AUTHORIZED
Section titled “VAULT_NOT_AUTHORIZED”| Property | Value |
|---|---|
| Title | Vault entry not authorized |
| HTTP status | 403 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Vault entry '{entry_name}' is not authorized for this session's slug.
Hint: The operator controls which sessions may use this entry.
Cause: The binding or group policy does not allow this principal and session slug.
Resolution: Operators edit the binding (slug globs, principals) on the Vault page.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
entry_name |
string |
yes | — |
EVALUATE_REQUIRED_OFF
Section titled “EVALUATE_REQUIRED_OFF”| Property | Value |
|---|---|
| Title | Entry requires evaluate disabled |
| HTTP status | 403 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Vault entry '{entry_name}' requires the session to have evaluate disabled (launch with disable_evaluate: true).
Hint: Relaunch the session with disable_evaluate: true.
Cause: The binding is marked require_no_evaluate and the session can run scripts.
Resolution: Launch with disable_evaluate: true before filling this entry.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
entry_name |
string |
yes | — |
DASHBOARD_DENIED
Section titled “DASHBOARD_DENIED”| Property | Value |
|---|---|
| Title | Fill denied by operator |
| HTTP status | 403 |
| Category | domain |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: Vault fill for '{entry_name}' was denied by the dashboard (or timed out waiting for confirmation).
Hint: Ask the operator to approve the fill, then retry.
Cause: The operator rejected the confirmation, or nobody answered before the deadline.
Resolution: Retry when an operator is available to confirm.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
request_id |
string |
yes | — |
entry_name |
string |
no | — |
VAULT_UNLOCK_FAILED
Section titled “VAULT_UNLOCK_FAILED”| Property | Value |
|---|---|
| Title | Vault unlock failed |
| HTTP status | 401 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Vault unlock failed ({mode}).
Hint: Create a new session token with bw unlock --raw and paste it again.
Cause: The backend rejected the session token (expired after bw lock or bw logout, or from another bw login), or the passphrase of a passphrase backend.
Resolution: Run bw unlock --raw as the user that runs BrowserHive and paste the new token, or export it as BW_SESSION before start.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
mode |
string |
yes | — |
VAULT_SYNC_UNSUPPORTED
Section titled “VAULT_SYNC_UNSUPPORTED”| Property | Value |
|---|---|
| Title | Vault sync unsupported |
| HTTP status | 400 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Vault backend '{backend}' does not support sync.
Hint: Nothing to do; this backend has no sync operation.
Cause: The backend capabilities report sync: false.
Resolution: Use a backend that supports sync, or skip the call.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
backend |
string |
yes | — |
VAULT_BACKEND_ERROR
Section titled “VAULT_BACKEND_ERROR”| Property | Value |
|---|---|
| Title | Vault backend error |
| HTTP status | 502 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Vault backend '{backend}' failed ({kind}).
Hint: Retry; if it persists, check the backend CLI on the host.
Cause: The backend CLI is missing, timed out, or exited with an error.
Resolution: Install or repair the backend CLI (bw) and retry.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
backend |
string |
yes | — |
kind |
one of not_installed, timeout, exit |
yes | — |
ATTENTION_REQUIRES_HTTP
Section titled “ATTENTION_REQUIRES_HTTP”| Property | Value |
|---|---|
| Title | Attention requires http |
| HTTP status | 400 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: '{tool}' requires the http transport; human-in-the-loop attention is not available under stdio.
Hint: Run the server with transport=http and admin=true.
Cause: Attention needs the shared, long-lived HTTP daemon and the dashboard; stdio is single-client.
Resolution: Start BrowserHive with --admin (http transport).
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
tool |
string |
yes | — |
ATTENTION_NOT_OPEN
Section titled “ATTENTION_NOT_OPEN”| Property | Value |
|---|---|
| Title | Attention request is not open |
| HTTP status | 409 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Attention request '{request_id}' is not open (status: {status}).
Hint: Refresh the queue.
Cause: The request was already resolved, rejected, timed out or cancelled.
Resolution: Nothing to do; the outcome is final.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
request_id |
string |
yes | — |
status |
string |
yes | — |
CONFIRM_NOT_OPEN
Section titled “CONFIRM_NOT_OPEN”| Property | Value |
|---|---|
| Title | Confirmation is not open |
| HTTP status | 409 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Vault confirmation '{request_id}' is not open (status: {status}).
Hint: Refresh the confirm queue.
Cause: The confirmation was already decided or expired.
Resolution: Nothing to do; the outcome is final.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
request_id |
string |
yes | — |
status |
string |
yes | — |
INPUT_NOT_PERMITTED
Section titled “INPUT_NOT_PERMITTED”| Property | Value |
|---|---|
| Title | Input not permitted |
| HTTP status | 409 |
| Category | domain |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: Input is not permitted on session '{session_id}': no takeover attention request is open.
Hint: Input is only accepted while a takeover attention request is open.
Cause: Live-view input is gated on an open takeover request from the agent.
Resolution: Wait for the agent to request attention in takeover mode.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
SCREENCAST_FAILED
Section titled “SCREENCAST_FAILED”| Property | Value |
|---|---|
| Title | Screencast failed |
| HTTP status | 502 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Screencast for session '{session_id}' failed: {reason}
Hint: Retry; if the session is closing the stream cannot start.
Cause: The CDP screencast could not be started or the bridge lost its page.
Resolution: Retry the live view; check the session is live.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
reason |
string |
yes | — |
TOOL_NOT_AVAILABLE
Section titled “TOOL_NOT_AVAILABLE”| Property | Value |
|---|---|
| Title | Tool not available |
| HTTP status | 400 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Tool '{tool}' is not available on this server (requires {requires}).
Hint: The tool needs a server feature that is off.
Cause: The tool pack requires a transport, vault or admin feature that is not enabled.
Resolution: Enable the feature on the server, or avoid the tool.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
tool |
string |
yes | — |
requires |
string |
yes | — |
INVALID_ARGUMENTS
Section titled “INVALID_ARGUMENTS”| Property | Value |
|---|---|
| Title | Invalid arguments |
| HTTP status | 400 |
| Category | domain |
| Retryable | different_args (retry only with different arguments) |
Message: Invalid arguments: {summary}
Hint: Fix the listed issues and call the tool again.
Cause: The tool arguments failed schema validation.
Resolution: Each issue names the path and what is wrong.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
issues |
object[] |
yes | each item: keys path, message |
TRACE_UNAVAILABLE
Section titled “TRACE_UNAVAILABLE”| Property | Value |
|---|---|
| Title | Trace unavailable |
| HTTP status | 404 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: No trace is available for this session.
Hint: Tracing is on when trace=true (default with admin).
Cause: Tracing was off for the session, or the trace failed to finalize.
Resolution: Enable trace and relaunch; see TRACE_START_FAILED warnings.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
enabled |
boolean |
yes | — |
SCREENSHOT_UNAVAILABLE
Section titled “SCREENSHOT_UNAVAILABLE”| Property | Value |
|---|---|
| Title | Screenshot unavailable |
| HTTP status | 404 |
| Category | domain |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: No screenshot is stored for event '{event_id}'.
Hint: Screenshots are kept per tool call while retention allows.
Cause: The event produced no screenshot, or retention removed it.
Resolution: Nothing to do; the artifact no longer exists.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
event_id |
string |
yes | — |
INTERNAL_ERROR
Section titled “INTERNAL_ERROR”| Property | Value |
|---|---|
| Title | Internal error |
| HTTP status | 500 |
| Category | domain |
| Retryable | backoff (retry later with backoff) |
Message: Internal error (ref {ref}).
Hint: Quote the ref to the operator; the logs hold the detail.
Cause: An unexpected failure that no typed code describes.
Resolution: Search the logs for the ref (request id) and file a bug if it repeats.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
ref |
string |
yes | — |
Boot errors
Section titled “Boot errors”Stop the process before it serves anything. The CLI prints [CODE] message and exits with the listed exit code.
| Code | Title | HTTP | Retryable |
|---|---|---|---|
ADMIN_REQUIRES_HTTP |
Dashboard requires http | 500 | never |
INSECURE_BIND_REFUSED |
Insecure bind refused | 500 | never |
PORT_IN_USE |
Port in use | 500 | never |
BIND_FAILED |
Bind failed | 500 | never |
CONFIG_INVALID |
Invalid configuration value | 400 | never |
CONFIG_UNKNOWN_KEY |
Unknown configuration key | 400 | never |
BLOCKLIST_LOAD_FAILED |
Blocklist could not be loaded | 400 | never |
DATA_DIR_UNWRITABLE |
Data directory not writable | 500 | never |
DATA_DIR_LOCKED |
Data directory in use | 409 | never |
DB_OPEN_FAILED |
Database could not be opened | 500 | never |
DB_NEWER_THAN_BINARY |
Database newer than this version | 500 | never |
MIGRATION_FAILED |
Migration failed | 500 | never |
DB_CORRUPT |
Database corrupt | 500 | never |
UNHANDLED |
Unhandled error | 500 | never |
RETENTION_FAILED |
Retention sweep failed | 500 | backoff |
STALE_BROWSER_PROCESSES |
Stale browser processes found | 500 | never |
ADMIN_REQUIRES_HTTP
Section titled “ADMIN_REQUIRES_HTTP”| Property | Value |
|---|---|
| Title | Dashboard requires http |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 3 |
Message: admin=true requires transport=http. The dashboard is not available under stdio.
Hint: Drop admin=true, or use transport=http.
Cause: admin=true was combined with transport=stdio; stdio is single-client and cannot host the dashboard.
Resolution: Run with the http transport (the default) to use the dashboard.
Details: none.
INSECURE_BIND_REFUSED
Section titled “INSECURE_BIND_REFUSED”| Property | Value |
|---|---|
| Title | Insecure bind refused |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 3 |
Message: Refusing to bind {host} without authentication. Set auth=token, or set allowInsecureBind=true to accept the risk.
Hint: Set auth=token for LAN exposure.
Cause: A non-loopback host was requested without auth=token and without allowInsecureBind=true.
Resolution: Enable token auth, or acknowledge the risk with allowInsecureBind=true.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
host |
string |
yes | — |
PORT_IN_USE
Section titled “PORT_IN_USE”| Property | Value |
|---|---|
| Title | Port in use |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 3 |
Message: Cannot listen on {host}:{port}: the port is already in use ({errno}).
Hint: Pick another port with –port, or stop the process holding it.
Cause: Another process (often a previous BrowserHive) is bound to the same host and port.
Resolution: Stop the other process or choose a free port.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
host |
string |
yes | — |
port |
integer |
yes | — |
errno |
string |
yes | — |
BIND_FAILED
Section titled “BIND_FAILED”| Property | Value |
|---|---|
| Title | Bind failed |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: Cannot listen on {host}:{port} ({errno}).
Hint: Check the address exists on this host and the port is permitted.
Cause: The listener could not bind for a reason other than a busy port (EACCES, EADDRNOTAVAIL…).
Resolution: Use an address assigned to this host and an unprivileged port.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
host |
string |
yes | — |
port |
integer |
yes | — |
errno |
string |
yes | — |
CONFIG_INVALID
Section titled “CONFIG_INVALID”| Property | Value |
|---|---|
| Title | Invalid configuration value |
| HTTP status | 400 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 64 |
Message: invalid value for {source}: {reason}
Hint: Run ‘browserhive config validate’ to see every problem.
Cause: A value failed its grammar, range or a cross-field rule.
Resolution: Fix the value at the named source; the grammar is in the message.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
key |
string |
yes | — |
source |
string |
yes | — |
reason |
string |
yes | — |
CONFIG_UNKNOWN_KEY
Section titled “CONFIG_UNKNOWN_KEY”| Property | Value |
|---|---|
| Title | Unknown configuration key |
| HTTP status | 400 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 64 |
Message: unknown key '{key}' in {source}.
Hint: Run ‘browserhive –help’ for the list of keys.
Cause: A flag, environment variable or config-file key is not in the registry (typo or removed knob).
Resolution: Use the suggested name; kebab-case flag spellings are not supported.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
key |
string |
yes | — |
source |
string |
yes | — |
suggestion |
string |
no | — |
BLOCKLIST_LOAD_FAILED
Section titled “BLOCKLIST_LOAD_FAILED”| Property | Value |
|---|---|
| Title | Blocklist could not be loaded |
| HTTP status | 400 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 3 |
Message: Cannot load blocklist {path}: {reason}
Hint: Check the path and file permissions.
Cause: The configured blocklist file is missing, unreadable or over the entry cap.
Resolution: Fix the file; a configured-but-unreadable blocklist is fatal by design.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
path |
string |
yes | — |
reason |
string |
yes | — |
DATA_DIR_UNWRITABLE
Section titled “DATA_DIR_UNWRITABLE”| Property | Value |
|---|---|
| Title | Data directory not writable |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: The data directory {path} is not writable.
Hint: Fix permissions or choose another dataDir.
Cause: The data directory could not be created with mode 0700 or is owned by another user.
Resolution: Point dataDir at a directory the server user owns.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
path |
string |
yes | — |
DATA_DIR_LOCKED
Section titled “DATA_DIR_LOCKED”| Property | Value |
|---|---|
| Title | Data directory in use |
| HTTP status | 409 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 3 |
Message: The data directory {path} is in use by another BrowserHive process (pid {pid}).
Hint: Stop the running server first, or point dataDir at another directory.
Cause: A live process holds <data-dir>/browserhive.lock; one server (or one maintenance command) owns a data directory at a time.
Resolution: Stop that process. A lock left by a crashed process is detected (its pid is gone) and replaced automatically.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
path |
string |
yes | — |
pid |
integer |
yes | — |
DB_OPEN_FAILED
Section titled “DB_OPEN_FAILED”| Property | Value |
|---|---|
| Title | Database could not be opened |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: Cannot open database {path}: {reason}
Hint: Run ‘browserhive db status’ for details.
Cause: SQLite refused to open the file (locked, permissions, wrong application_id).
Resolution: Check for another running server and file permissions.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
path |
string |
yes | — |
reason |
string |
yes | — |
DB_NEWER_THAN_BINARY
Section titled “DB_NEWER_THAN_BINARY”| Property | Value |
|---|---|
| Title | Database newer than this version |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 3 |
Message: The database schema (v{db_version}, readable from v{min_reader_version}) is newer than this binary supports (v{binary_version}).
Hint: Upgrade BrowserHive, or restore the pre-upgrade backup with ‘browserhive db restore
Cause: A newer BrowserHive migrated the database past this binary’s compatibility window (D-04).
Resolution: Upgrade, or restore the named backup to downgrade.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
db_version |
integer |
yes | — |
min_reader_version |
integer |
yes | — |
binary_version |
integer |
yes | — |
backup_path |
string |
no | — |
MIGRATION_FAILED
Section titled “MIGRATION_FAILED”| Property | Value |
|---|---|
| Title | Migration failed |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: Migration '{name}' (v{from} → v{to}) failed. The pre-migration backup is at {backup_path}.
Hint: The database was rolled back; report the failure with the log.
Cause: A migration step raised inside the transaction; the transaction was rolled back.
Resolution: File a bug with the log; restore the backup if the database is unusable.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
from |
integer |
yes | — |
to |
integer |
yes | — |
name |
string |
yes | — |
backup_path |
string |
yes | — |
DB_CORRUPT
Section titled “DB_CORRUPT”| Property | Value |
|---|---|
| Title | Database corrupt |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: The database {path} is corrupt; it was moved to {quarantine_path}.
Hint: Restore a backup with ‘browserhive db restore
Cause: PRAGMA quick_check failed or SQLite reported corruption.
Resolution: Restore the most recent backup from backups/.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
path |
string |
yes | — |
quarantine_path |
string |
yes | — |
UNHANDLED
Section titled “UNHANDLED”| Property | Value |
|---|---|
| Title | Unhandled error |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: Unhandled {kind} reached the process handler: {name}.
Hint: Check the log for the stack; the server keeps running when the failure is contained.
Cause: A promise rejected with no handler or an exception escaped every boundary; the CLI process handlers record it as a degradation (spec 10 §3).
Resolution: Report the log line; repeated occurrences on /system.degradations indicate a bug in a background task.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
kind |
one of exception, rejection |
yes | — |
name |
string |
yes | — |
RETENTION_FAILED
Section titled “RETENTION_FAILED”| Property | Value |
|---|---|
| Title | Retention sweep failed |
| HTTP status | 500 |
| Category | boot |
| Retryable | backoff (retry later with backoff) |
| Exit code | 1 |
Message: Retention step {step} failed: {reason}
Hint: The sweep retries on the next interval; check disk space and file permissions.
Cause: A step of the periodic retention sweep (row pruning, byte cap, vacuum or artifact enqueue) threw. Recorded as a degradation, never fatal.
Resolution: Fix the underlying cause (disk, permissions, locks); the degradation resolves on the next clean pass.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
step |
string |
yes | — |
reason |
string |
yes | — |
STALE_BROWSER_PROCESSES
Section titled “STALE_BROWSER_PROCESSES”| Property | Value |
|---|---|
| Title | Stale browser processes found |
| HTTP status | 500 |
| Category | boot |
| Retryable | never (do not retry; the request cannot succeed as sent) |
| Exit code | 1 |
Message: {count} browser process(es) from a previous run are still alive.
Hint: Stop them manually if they hold profile locks or memory.
Cause: Chromium processes launched by an earlier BrowserHive survived its exit (crash or SIGKILL). Recorded as a boot-time degradation, never fatal.
Resolution: Kill the listed processes; they are not adopted by the new server.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
count |
integer |
yes | — |
Authentication errors
Section titled “Authentication errors”Returned by the REST API, /mcp and the WebSocket handshake.
| Code | Title | HTTP | Retryable |
|---|---|---|---|
UNAUTHORIZED |
Unauthorized | 401 | never |
INVALID_CREDENTIALS |
Invalid credentials | 401 | never |
FORBIDDEN |
Forbidden | 403 | never |
PASSWORD_CHANGE_REQUIRED |
Password change required | 403 | after_operator |
BAD_CURRENT_PASSWORD |
Current password incorrect | 400 | different_args |
WEAK_PASSWORD |
Password too weak | 400 | different_args |
UNAUTHORIZED
Section titled “UNAUTHORIZED”| Property | Value |
|---|---|
| Title | Unauthorized |
| HTTP status | 401 |
| Category | auth |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Authentication required.
Hint: Log in, or send a valid bearer token.
Cause: No credential was presented, or the presented one is invalid or expired.
Resolution: Authenticate with the dashboard session cookie or a bearer token.
Details: none.
INVALID_CREDENTIALS
Section titled “INVALID_CREDENTIALS”| Property | Value |
|---|---|
| Title | Invalid credentials |
| HTTP status | 401 |
| Category | auth |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Invalid username or password.
Hint: Check the password; reset it with browserhive admin reset-password.
Cause: The login password did not match, or the account is locked out.
Resolution: Retry with the correct password or reset it from the CLI.
Details: none.
FORBIDDEN
Section titled “FORBIDDEN”| Property | Value |
|---|---|
| Title | Forbidden |
| HTTP status | 403 |
| Category | auth |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: This action requires the '{scope}' scope.
Hint: Use a principal that holds the scope.
Cause: The principal lacks the scope the route or tool declares.
Resolution: Operators hold every scope; issue an operator token with the needed scope.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
scope |
string |
yes | — |
PASSWORD_CHANGE_REQUIRED
Section titled “PASSWORD_CHANGE_REQUIRED”| Property | Value |
|---|---|
| Title | Password change required |
| HTTP status | 403 |
| Category | auth |
| Retryable | after_operator (retry after an operator acts (unlock the vault, resolve a request, change policy)) |
Message: The seed password must be changed before continuing.
Hint: Change the password on the login screen.
Cause: The operator account still uses the generated seed password.
Resolution: Set a new password; the seed file is shredded afterwards.
Details: none.
BAD_CURRENT_PASSWORD
Section titled “BAD_CURRENT_PASSWORD”| Property | Value |
|---|---|
| Title | Current password incorrect |
| HTTP status | 400 |
| Category | auth |
| Retryable | different_args (retry only with different arguments) |
Message: The current password is incorrect.
Hint: Re-enter the current password.
Cause: The password-change request carried a wrong current password.
Resolution: Retry with the correct current password.
Details: none.
WEAK_PASSWORD
Section titled “WEAK_PASSWORD”| Property | Value |
|---|---|
| Title | Password too weak |
| HTTP status | 400 |
| Category | auth |
| Retryable | different_args (retry only with different arguments) |
Message: The new password must be at least {min_length} characters long.
Hint: Choose a longer password.
Cause: The new password is shorter than the minimum length.
Resolution: Use at least the minimum number of characters.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
min_length |
integer |
yes | — |
Transport errors
Section titled “Transport errors”Protocol-level failures of HTTP and WebSocket requests (validation, limits, conflicts).
| Code | Title | HTTP | Retryable |
|---|---|---|---|
ORIGIN_NOT_ALLOWED |
Origin not allowed | 403 | never |
HOST_NOT_ALLOWED |
Host not allowed | 421 | never |
RATE_LIMITED |
Rate limited | 429 | backoff |
PAYLOAD_TOO_LARGE |
Payload too large | 413 | different_args |
VALIDATION_FAILED |
Validation failed | 400 | different_args |
NOT_FOUND |
Not found | 404 | never |
METHOD_NOT_ALLOWED |
Method not allowed | 405 | never |
CONFLICT |
Conflict | 409 | different_args |
NOT_ACCEPTABLE |
Not acceptable | 406 | different_args |
WS_PROTOCOL_ERROR |
WebSocket protocol error | 400 | never |
WS_OVERLOADED |
WebSocket overloaded | 503 | backoff |
ORIGIN_NOT_ALLOWED
Section titled “ORIGIN_NOT_ALLOWED”| Property | Value |
|---|---|
| Title | Origin not allowed |
| HTTP status | 403 |
| Category | transport |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The request Origin is not allowed.
Hint: Open the dashboard from the server URL itself.
Cause: A browser request carried an Origin that does not match the server (CSRF guard).
Resolution: Use the dashboard served by this BrowserHive; no cross-origin access is allowed.
Details: none.
HOST_NOT_ALLOWED
Section titled “HOST_NOT_ALLOWED”| Property | Value |
|---|---|
| Title | Host not allowed |
| HTTP status | 421 |
| Category | transport |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The request Host header is not allowed.
Hint: Address the server by the host it is bound to.
Cause: DNS-rebinding guard: the Host header does not match the bound host.
Resolution: Use the bound host or IP in the URL.
Details: none.
RATE_LIMITED
Section titled “RATE_LIMITED”| Property | Value |
|---|---|
| Title | Rate limited |
| HTTP status | 429 |
| Category | transport |
| Retryable | backoff (retry later with backoff) |
Message: Too many requests. Retry after {retry_after_ms} ms.
Hint: Back off for the given interval.
Cause: The client exceeded the login or API rate limit.
Resolution: Wait for retry_after_ms and retry.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
retry_after_ms |
integer |
yes | — |
PAYLOAD_TOO_LARGE
Section titled “PAYLOAD_TOO_LARGE”| Property | Value |
|---|---|
| Title | Payload too large |
| HTTP status | 413 |
| Category | transport |
| Retryable | different_args (retry only with different arguments) |
Message: The request body exceeds the limit of {limit_bytes} bytes.
Hint: Send a smaller body.
Cause: The body is larger than the route’s limit.
Resolution: Reduce the payload size.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
limit_bytes |
integer |
yes | — |
VALIDATION_FAILED
Section titled “VALIDATION_FAILED”| Property | Value |
|---|---|
| Title | Validation failed |
| HTTP status | 400 |
| Category | transport |
| Retryable | different_args (retry only with different arguments) |
Message: The request failed validation.
Hint: Each issue names the field and what is wrong.
Cause: Params, query or body did not match the route schema; unknown keys are errors.
Resolution: Fix the listed fields.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
issues |
object[] |
yes | each item: keys path, message, code |
NOT_FOUND
Section titled “NOT_FOUND”| Property | Value |
|---|---|
| Title | Not found |
| HTTP status | 404 |
| Category | transport |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The requested resource does not exist.
Hint: Check the path and id.
Cause: No route or resource matches the request.
Resolution: Consult /api/v1/docs for the route table.
Details: none.
METHOD_NOT_ALLOWED
Section titled “METHOD_NOT_ALLOWED”| Property | Value |
|---|---|
| Title | Method not allowed |
| HTTP status | 405 |
| Category | transport |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The method is not allowed for this resource.
Hint: Use one of the allowed methods.
Cause: The route exists but not for this HTTP method.
Resolution: See details.allow and the Allow header.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
allow |
string[] |
yes | — |
CONFLICT
Section titled “CONFLICT”| Property | Value |
|---|---|
| Title | Conflict |
| HTTP status | 409 |
| Category | transport |
| Retryable | different_args (retry only with different arguments) |
Message: The resource changed since you last read it.
Hint: Reload the resource and retry with the current version.
Cause: An optimistic-concurrency check (If-Match/version) failed; the HTTP layer may use 412.
Resolution: Re-read, then resubmit with current_version.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
current_version |
integer |
no | — |
NOT_ACCEPTABLE
Section titled “NOT_ACCEPTABLE”| Property | Value |
|---|---|
| Title | Not acceptable |
| HTTP status | 406 |
| Category | transport |
| Retryable | different_args (retry only with different arguments) |
Message: None of the requested media types is supported.
Hint: Ask for one of the supported types.
Cause: The Accept header lists no representation the route can produce.
Resolution: See details.supported.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
supported |
string[] |
yes | — |
WS_PROTOCOL_ERROR
Section titled “WS_PROTOCOL_ERROR”| Property | Value |
|---|---|
| Title | WebSocket protocol error |
| HTTP status | 400 |
| Category | transport |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The WebSocket client violated the protocol.
Hint: Reconnect with a compliant client.
Cause: Malformed envelope, unknown command, wrong protocol version, or a command before subscribe.
Resolution: Fix the client; the socket is closed with the code in spec 03 §6.4.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
violations |
string[] |
yes | — |
WS_OVERLOADED
Section titled “WS_OVERLOADED”| Property | Value |
|---|---|
| Title | WebSocket overloaded |
| HTTP status | 503 |
| Category | transport |
| Retryable | backoff (retry later with backoff) |
Message: The connection fell too far behind ({buffered_bytes} bytes buffered).
Hint: Reconnect and resubscribe with the last cursor.
Cause: Backpressure: the client did not drain the feed within the buffer bounds.
Resolution: Reconnect; the feed replays from your cursor or asks for a resync.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
buffered_bytes |
integer |
yes | — |
Audit outcomes
Section titled “Audit outcomes”Recorded in the audit trail (vault log, attention history). Some are also returned inside a tool result.
| Code | Title | HTTP | Retryable |
|---|---|---|---|
ORIGIN_MISMATCH |
Origin not on the allow-list | 403 | different_args |
VAULT_FILL_AUTH_FAILED |
Vault fill: authentication failed | 500 | never |
VAULT_FILL_BLOCKED |
Vault fill: blocked | 500 | never |
VAULT_LIST_DENIED |
Vault list: denied | 500 | never |
ATTENTION_REJECTED |
Attention: rejected | 500 | never |
ATTENTION_TIMEOUT |
Attention: timed out | 500 | never |
ATTENTION_CANCELLED |
Attention: cancelled | 500 | never |
ORIGIN_MISMATCH
Section titled “ORIGIN_MISMATCH”| Property | Value |
|---|---|
| Title | Origin not on the allow-list |
| HTTP status | 403 |
| Category | audit |
| Retryable | different_args (retry only with different arguments) |
Message: Origin '{page_origin}' is not on the allow-list for vault entry '{entry_name}'.
Hint: Navigate to an allowed origin before filling.
Cause: The page origin at fill time did not match the binding’s allowed origins.
Resolution: Fill only on the sites the operator bound the entry to.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
page_origin |
string |
yes | — |
entry_name |
string |
yes | — |
allowed |
string[] |
yes | — |
VAULT_FILL_AUTH_FAILED
Section titled “VAULT_FILL_AUTH_FAILED”| Property | Value |
|---|---|
| Title | Vault fill: authentication failed |
| HTTP status | 500 |
| Category | audit |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The vault fill completed but the site did not accept the credentials.
Hint: Classification of a returned vault_fill status; not an exception.
Cause: vault_fill returned auth_failed.
Resolution: Check the credential in the vault; nothing to retry automatically.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
entry_name |
string |
yes | — |
VAULT_FILL_BLOCKED
Section titled “VAULT_FILL_BLOCKED”| Property | Value |
|---|---|
| Title | Vault fill: blocked |
| HTTP status | 500 |
| Category | audit |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The vault fill was blocked by policy.
Hint: Classification of a returned vault_fill status; not an exception.
Cause: vault_fill returned blocked (policy gate refused).
Resolution: See the reason; operators adjust bindings and policies.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
entry_name |
string |
yes | — |
reason |
string |
no | — |
VAULT_LIST_DENIED
Section titled “VAULT_LIST_DENIED”| Property | Value |
|---|---|
| Title | Vault list: denied |
| HTTP status | 500 |
| Category | audit |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The vault listing was denied for this session.
Hint: Classification of a returned vault_list_available status; not an exception.
Cause: vault_list_available returned no entries because policy denied the session.
Resolution: Operators adjust bindings and policies.
Details: none.
ATTENTION_REJECTED
Section titled “ATTENTION_REJECTED”| Property | Value |
|---|---|
| Title | Attention: rejected |
| HTTP status | 500 |
| Category | audit |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: The attention request was rejected.
Hint: Classification of a returned request_attention status; not an exception.
Cause: The operator rejected the request, or the session closed while it was open.
Resolution: Read the returned message; continue or stop the task accordingly.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
request_id |
string |
yes | — |
ATTENTION_TIMEOUT
Section titled “ATTENTION_TIMEOUT”| Property | Value |
|---|---|
| Title | Attention: timed out |
| HTTP status | 500 |
| Category | audit |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Attention request timed out; the operator was not available to respond.
Hint: Classification of a returned request_attention status; not an exception.
Cause: Nobody resolved the request before its deadline.
Resolution: Retry later with a longer wait, or proceed without the operator.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
request_id |
string |
yes | — |
ATTENTION_CANCELLED
Section titled “ATTENTION_CANCELLED”| Property | Value |
|---|---|
| Title | Attention: cancelled |
| HTTP status | 500 |
| Category | audit |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: Client cancelled the attention request.
Hint: Classification of a returned request_attention status; not an exception.
Cause: The MCP client disconnected or sent notifications/cancelled.
Resolution: Nothing to do.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
request_id |
string |
yes | — |
Warnings
Section titled “Warnings”Non-fatal degradations recorded on a session or in the system events list; the operation continues.
| Code | Title | HTTP | Retryable |
|---|---|---|---|
EXECUTABLE_PATH_OVERRIDE |
Executable path override | 500 | never |
TRACE_START_FAILED |
Trace could not start | 500 | never |
TRACE_FINALIZE_FAILED |
Trace could not be finalized | 500 | never |
STEALTH_INIT_FAILED |
Stealth init failed | 500 | never |
BLOCKLIST_ROUTE_FAILED |
Blocklist route failed | 500 | never |
BYO_PROXY_UNSEEDED |
BYO proxy: geo not seeded | 500 | never |
VIEWPORT_OVERRIDE_UNASSERTED |
Viewport override: display not asserted | 500 | never |
IDENTITY_SEED_SAVE_FAILED |
Identity seed not saved | 500 | never |
REAP_DEAD_FAILED |
Dead session reap failed | 500 | never |
CDP_SESSION_LEAKED |
CDP session leaked | 500 | never |
SCREENSHOT_ARCHIVE_FAILED |
Screenshot archive failed | 500 | never |
EXECUTABLE_PATH_OVERRIDE
Section titled “EXECUTABLE_PATH_OVERRIDE”| Property | Value |
|---|---|
| Title | Executable path override |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: A launch option set executablePath, which disables channel routing.
Resolution: Prefer channel; use executablePath only for custom builds.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
TRACE_START_FAILED
Section titled “TRACE_START_FAILED”| Property | Value |
|---|---|
| Title | Trace could not start |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: Playwright tracing failed to start for the session; the session continues without a trace.
Resolution: Check disk space and the session directory permissions.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
TRACE_FINALIZE_FAILED
Section titled “TRACE_FINALIZE_FAILED”| Property | Value |
|---|---|
| Title | Trace could not be finalized |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: Stopping the trace failed or exceeded the 10 s cap at close.
Resolution: The trace may be incomplete; check disk space.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
STEALTH_INIT_FAILED
Section titled “STEALTH_INIT_FAILED”| Property | Value |
|---|---|
| Title | Stealth init failed |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: The CDP identity override could not be applied; the session runs with reduced stealth.
Resolution: Check the driver (Patchright/Playwright) version compatibility.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
BLOCKLIST_ROUTE_FAILED
Section titled “BLOCKLIST_ROUTE_FAILED”| Property | Value |
|---|---|
| Title | Blocklist route failed |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: The network-level blocklist route could not be installed; tool-level enforcement still applies.
Resolution: Check the driver version; report if it repeats.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
BYO_PROXY_UNSEEDED
Section titled “BYO_PROXY_UNSEEDED”| Property | Value |
|---|---|
| Title | BYO proxy: geo not seeded |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: A caller-supplied proxy suppresses geo-derived identity because the exit location is unknown.
Resolution: Pass locale/timezoneId explicitly when using your own proxy.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
VIEWPORT_OVERRIDE_UNASSERTED
Section titled “VIEWPORT_OVERRIDE_UNASSERTED”| Property | Value |
|---|---|
| Title | Viewport override: display not asserted |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: A caller-supplied viewport disables the display-coherence assertion of the fingerprint.
Resolution: Omit viewport to let the identity pick a coherent display.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
IDENTITY_SEED_SAVE_FAILED
Section titled “IDENTITY_SEED_SAVE_FAILED”| Property | Value |
|---|---|
| Title | Identity seed not saved |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: The .identity.json sidecar could not be written with the full profile.
Resolution: Check the auth-states directory permissions.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
REAP_DEAD_FAILED
Section titled “REAP_DEAD_FAILED”| Property | Value |
|---|---|
| Title | Dead session reap failed |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: Closing a dead session raised; the sweeper will retry.
Resolution: No action; report if it repeats for the same session.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
CDP_SESSION_LEAKED
Section titled “CDP_SESSION_LEAKED”| Property | Value |
|---|---|
| Title | CDP session leaked |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: A CDP session was still attached when its page closed and had to be pruned late.
Resolution: No action; report if it repeats.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |
SCREENSHOT_ARCHIVE_FAILED
Section titled “SCREENSHOT_ARCHIVE_FAILED”| Property | Value |
|---|---|
| Title | Screenshot archive failed |
| HTTP status | 500 |
| Category | warning |
| Retryable | never (do not retry; the request cannot succeed as sent) |
Message: {message}
Hint: Session warning: logged and broadcast on session:
Cause: A tool screenshot could not be written to the session directory.
Resolution: Check disk space and permissions.
Details:
| Field | Type | Required | Constraints |
|---|---|---|---|
session_id |
string |
yes | — |
message |
string |
yes | — |
details |
object |
no | additional keys allowed |