SmithersErrorInstance is a typed, code-bearing Error subclass used throughout Smithers internals. It surfaces when runWorkflow throws, in NodeFailed events emitted during execution, and as JSON in HTTP API error responses. The imports below are the full error utility surface.
build agent command: undefined is not an object (evaluating 'schema._zod.def'):
your task output schema is a Zod v3 object. Smithers reads schema metadata
via Zod v4 internals (_zod.def). Install Zod v4 (bun add zod@^4) and import
z from it. This is a deterministic configuration error; re-running will not fix
it.SmithersErrorInstance carries three pieces of documentation metadata:
| Field | Meaning |
|---|---|
message | Human-readable description followed by a docs URL, e.g. "Input failed validation. See https://…" |
summary | Raw message without the docs suffix. |
docsUrl | Reference URL for Smithers errors. |
KnownSmithersErrorCode for an exhaustive switch over built-in Smithers codes. SmithersErrorCode includes the (string & {}) escape hatch for user-defined custom codes.
| Export | Kind | Description |
|---|---|---|
SmithersErrorInstance | class | Runtime error class used throughout Smithers internals. |
isSmithersError(err) | function | Type guard for values carrying a Smithers-style code. |
isKnownSmithersErrorCode(code) | function | Narrows a string to the built-in exhaustive error-code union. |
knownSmithersErrorCodes | value | Array of every built-in Smithers error code documented on this page. |
getSmithersErrorDocsUrl(code) | function | Returns the docs URL appended to built-in error messages. |
getSmithersErrorDefinition(code) | function | Returns category, description, and details metadata for known codes. |
errorToJson(err) | function | Serializes name, message, summary, docsUrl, code, details, cause, and stack. |
ERROR_REFERENCE_URL | value | Base docs URL for Smithers runtime errors. |
KnownSmithersErrorCode | type | Exact built-in Smithers code union. |
SmithersErrorCode | type | Built-in codes plus the custom string escape hatch. |
SmithersError | type | Public typed shape for serialized Smithers errors. |
Engine
| Code | When | Details |
|---|---|---|
INVALID_INPUT | Workflow input fails validation or the runtime receives a non-object input payload. | — |
MISSING_INPUT | A resume run references an input row that is missing from the database. | — |
MISSING_INPUT_TABLE | The workflow schema does not expose the expected input table during resume or hydration. | — |
RESUME_METADATA_MISMATCH | Stored run metadata no longer matches the workflow being resumed. Editing the workflow file or an imported module between stop and resume triggers this (resume hashes file content, not git, so no commit is required). Fork/replay onto the edit or start a fresh run; revert the file to resume the original run. | mismatches, existing, current |
UNKNOWN_OUTPUT_SCHEMA | A task references an output table that is not present in the schema registry. | — |
INVALID_OUTPUT | Agent output cannot be parsed or validated against the declared output schema. | — |
WORKTREE_CREATE_FAILED | Smithers fails to create or hydrate a git or jj worktree for a task. | { worktreePath, vcsType, branch? } |
VCS_NOT_FOUND | No supported git or jj repository root can be found for the workflow. | { rootDir } |
SNAPSHOT_NOT_FOUND | A requested time-travel snapshot or frame does not exist. | { runId, frameNo } |
VCS_WORKSPACE_CREATE_FAILED | Smithers fails to materialize a jj workspace for time-travel or replay. | { runId, frameNo, vcsPointer, workspacePath } |
TASK_TIMEOUT | A task compute callback exceeds its configured timeout. | { nodeId, attempt, timeoutMs } |
TASK_HIJACK_UNSUPPORTED | A task requests auto-hijack but its agent cannot provide a resumable session or conversation. | { nodeId, agentId? } |
TASK_FORK_SOURCE_NOT_COMPLETE | A forked task began executing but its fork source has not completed, so no session snapshot exists yet. | { nodeId, forkSource } |
TASK_FORK_SESSION_UNAVAILABLE | A <Task fork> cannot obtain a usable agent session snapshot, either because the forking task is not an agent task or because the source completed without producing a forkable conversation (e.g. a compute/static, skipped, or cancelled source). | { nodeId, forkSource } |
TASK_ABORTED | A running task is aborted through an AbortSignal or shutdown path. | — |
RUN_NOT_FOUND | A CLI or engine command references a run ID that does not exist in the database. | { runId } |
NODE_NOT_FOUND | A CLI command references a node ID that does not exist for the given run. | { runId, nodeId } |
SANDBOX_BUNDLE_INVALID | A sandbox bundle fails validation (missing README, invalid manifest, etc.). | { bundlePath } |
SANDBOX_BUNDLE_TOO_LARGE | A sandbox bundle exceeds the maximum allowed size. | { bundlePath, maxBytes } |
WORKFLOW_EXECUTION_FAILED | A child or builder workflow exits unsuccessfully without surfacing a typed error payload. | { status } |
SANDBOX_EXECUTION_FAILED | Sandbox setup or execution fails before a more specific sandbox error can be emitted. | { sandboxId, runId?, maxConcurrent?, activeSandboxCount? } |
TASK_HEARTBEAT_TIMEOUT | A task heartbeat timeout is exceeded while the task is still in progress. | { nodeId, iteration, attempt, timeoutMs, staleForMs, lastHeartbeatAtMs } |
HEARTBEAT_PAYLOAD_TOO_LARGE | A task heartbeat payload exceeds the maximum persisted checkpoint size. | { dataSizeBytes, maxBytes } |
HEARTBEAT_PAYLOAD_NOT_JSON_SERIALIZABLE | A task heartbeat payload contains values that cannot be serialized to JSON. | { path, valueType? } |
RUN_CANCELLED | A run is cancelled while runtime work is still active. | { runId } |
RUN_NOT_RESUMABLE | A resume request targets a run state that cannot be resumed. | { runId, status } |
RUN_OWNER_ALIVE | A resume attempt is skipped because the process that started the run is still alive (heartbeating). This is normal; it prevents two processes from running the same workflow simultaneously. | { runId, runtimeOwnerId } |
RUN_STILL_RUNNING | A recovery or resume operation finds a run that is still active. | { runId } |
RUN_RESUME_CLAIM_LOST | A runtime loses the resume claim before it can update the run. | { runId, runtimeOwnerId } |
RUN_RESUME_CLAIM_FAILED | A runtime cannot claim a stale run for resume. | { runId, runtimeOwnerId } |
RUN_RESUME_ACTIVATION_FAILED | A claimed run cannot be moved back into active execution. | { runId, runtimeOwnerId } |
RUN_HIJACKED | A run is interrupted because another runtime hijacked execution. | { runId, hijackTarget } |
CONTINUATION_STATE_TOO_LARGE | Continue-as-new state exceeds the configured serialized size limit. | { runId, sizeBytes, maxBytes } |
INVALID_CONTINUATION_STATE | Continue-as-new state cannot be parsed or applied. | — |
RALPH_MAX_REACHED | A Ralph loop reaches maxIterations with fail-on-max behavior. | { ralphId, maxIterations } |
SCHEDULER_ERROR | The scheduler cannot produce a valid execution decision. | — |
SESSION_ERROR | The workflow session state machine reaches an invalid or failed state. | — |
Components
| Code | When | Details |
|---|---|---|
TASK_ID_REQUIRED | <Task> is missing a valid string id. | — |
TASK_MISSING_OUTPUT | <Task> is missing its output prop. | { nodeId } |
TASK_FORK_SOURCE_NOT_FOUND | A <Task fork> references a source task id that is not present in the workflow graph, including a source that exists only in an unselected branch. | { nodeId, forkSource } |
TASK_FORK_CYCLE | A <Task fork> introduces a dependency cycle, directly or indirectly. | { nodeId, forkSource } |
DUPLICATE_ID | Two nodes with the same runtime id are mounted in one workflow graph. | { kind, id } |
NESTED_LOOP | <Loop> or <Ralph> is nested inside another loop construct that Smithers does not support. | — |
WORKTREE_EMPTY_PATH | <Worktree> is mounted with an empty path. | — |
MDX_PRELOAD_INACTIVE | A prompt object is rendered without the MDX preload layer being active. | — |
CONTEXT_OUTSIDE_WORKFLOW | Workflow context access happens outside an active Smithers workflow render. | — |
MISSING_OUTPUT | Code calls ctx.output() for a node result that does not exist. | { nodeId, iteration } |
DEP_NOT_SATISFIED | A typed dep on <Task> references an upstream output that has not been produced yet. | { taskId, depKey, resolvedNodeId } |
ASPECT_BUDGET_EXCEEDED | An Aspects budget (tokens or latency) has been exceeded. | { kind, limit, current } |
APPROVAL_OUTSIDE_TASK | <Approval> is resolved outside the active task runtime. | — |
APPROVAL_OPTIONS_REQUIRED | An approval mode that requires explicit options is missing them. | — |
WORKFLOW_MISSING_DEFAULT | A workflow module does not export a default Smithers workflow. | — |
Tools
| Code | When | Details |
|---|---|---|
TOOL_PATH_INVALID | A filesystem tool receives a non-string path. | — |
TOOL_PATH_ESCAPE | A filesystem tool resolves a path outside the sandbox root, including through symlinks. | — |
TOOL_FILE_TOO_LARGE | A read or edit operation exceeds the configured file size limit. | — |
TOOL_CONTENT_TOO_LARGE | A write operation exceeds the configured content size limit. | — |
TOOL_PATCH_TOO_LARGE | An edit patch exceeds the configured patch size limit. | — |
TOOL_PATCH_FAILED | A unified diff patch cannot be applied to the target file. | — |
TOOL_NETWORK_DISABLED | The bash tool tries to access the network while network access is disabled. | — |
TOOL_GIT_REMOTE_DISABLED | The bash tool attempts a remote git operation while network access is disabled. | — |
TOOL_COMMAND_FAILED | A bash tool command exits with a non-zero status. | — |
TOOL_GREP_FAILED | The grep tool fails with an rg execution error. | — |
Agents
| Code | When | Details |
|---|---|---|
AGENT_CLI_ERROR | A CLI-backed agent exits unsuccessfully, streams an explicit error, or its RPC transport fails. | — |
AGENT_QUOTA_EXCEEDED | An agent provider returns a usage-limit or quota error. The failure is transient; retries are preserved and the run pauses until the reset time. | { agentId?, agentEngine?, agentModel?, quotaResetAtMs?, resetHint? } |
AGENT_CONFIG_INVALID | A CLI-backed agent fails with a non-retryable configuration error such as an unknown model, missing LLM, or unsupported model. | — |
AGENT_RPC_FILE_ARGS | Pi RPC mode is used with file arguments that the transport does not support. | — |
AGENT_BUILD_COMMAND | An agent implementation forbids buildCommand() because it uses a custom generate() transport. | — |
AGENT_DIAGNOSTIC_TIMEOUT | An internal agent diagnostic check exceeds the per-check timeout budget. | — |
Database
| Code | When | Details |
|---|---|---|
DB_MISSING_COLUMNS | A table used by Smithers does not expose required columns such as runId or nodeId. | — |
DB_REQUIRES_BUN_SQLITE | The database adapter is not backed by a Bun SQLite client with exec(). | — |
DB_QUERY_FAILED | A database read query throws or rejects while running inside an Effect. | — |
DB_WRITE_FAILED | A database write or migration fails, including after SQLite retry exhaustion. | — |
SMITHERS_MIGRATION_REQUIRED | A legacy bun:sqlite store has run data but the resolved backend is PGlite/Postgres, so the history would be invisible until you run smithers migrate. | { dbPath, runCount, schemaVersion, resolvedBackend } |
STORAGE_ERROR | A storage service operation fails before surfacing a more specific database code. | — |
Migration errors
smithers migrate preserves the source SQLite store by default. If the legacy
smithers.db cannot be copied into the target backend, Smithers leaves the
original file untouched and reports the first actionable failure.
Corrupt, malformed, encrypted, or non-SQLite source files surface as
DB_QUERY_FAILED with the source dbPath in details. The error message tells
the operator to verify the file with sqlite3 <dbPath> 'PRAGMA integrity_check'
and restore from backup or start fresh if SQLite confirms corruption.
Source files that exist but cannot be opened also surface as DB_QUERY_FAILED.
That message points at the common operational causes: another process holding the
file, unreadable permissions, or a copied SQLite file missing its
smithers.db-wal / smithers.db-shm sidecars.
For Postgres migrations, smithers migrate --to postgres validates the target
connection string before opening the source store. Missing --url,
SMITHERS_POSTGRES_URL, or DATABASE_URL fails fast with INVALID_INPUT so
connection setup problems are not hidden behind unrelated source-store errors.
Effect / Runtime
| Code | When | Details |
|---|---|---|
INTERNAL_ERROR | An unexpected internal exception crossed an Effect boundary without a more specific Smithers code. | — |
PROCESS_ABORTED | A spawned child process is aborted by signal or shutdown. | { command, args, cwd } |
PROCESS_TIMEOUT | A spawned child process exceeds its total timeout. | { command, args, cwd, timeoutMs } |
PROCESS_IDLE_TIMEOUT | A spawned child process stops producing output longer than its idle timeout. | { command, args, cwd, idleTimeoutMs } |
PROCESS_SPAWN_FAILED | The runtime cannot spawn the requested child process. | { command, args, cwd } |
TASK_RUNTIME_UNAVAILABLE | Builder task runtime APIs are accessed outside an executing step. | — |
Hot Reload
| Code | When | Details |
|---|---|---|
SCHEMA_CHANGE_HOT | Hot reload detects a schema change that requires a full restart. | — |
HOT_OVERLAY_FAILED | Building or cleaning the generated hot-reload overlay fails. | — |
HOT_RELOAD_INVALID_MODULE | A hot-reloaded workflow module does not export a valid default workflow build. | — |
Scorers
| Code | When | Details |
|---|---|---|
SCORER_FAILED | A scorer throws or rejects while Smithers is evaluating a result. | — |
CLI
| Code | When | Details |
|---|---|---|
INVALID_EVENTS_OPTIONS | The smithers events command receives invalid filter options. | — |
WORKFLOW_EXISTS | The workflow creation CLI refuses to overwrite an existing workflow file. | — |
CLI_DB_NOT_FOUND | A CLI command cannot find a nearby smithers.db file. | — |
CLI_AGENT_UNSUPPORTED | The ask command selects an agent integration that Smithers does not support in that mode. | — |
Integrations
| Code | When | Details |
|---|---|---|
PI_HTTP_ERROR | The Pi or server integration receives a non-success HTTP response from Smithers. | — |
EXTERNAL_BUILD_FAILED | An external workflow host fails to build a Smithers HostNode payload. | { scriptPath, error?, exitCode?, stderr?, stdout? } |
SCHEMA_DISCOVERY_FAILED | External workflow schema discovery fails or returns invalid output. | { scriptPath, error?, exitCode?, stderr? } |
OPENAPI_SPEC_LOAD_FAILED | An OpenAPI spec cannot be loaded or parsed. | — |
OPENAPI_OPERATION_NOT_FOUND | The requested operationId does not exist in the OpenAPI spec. | — |
OPENAPI_TOOL_EXECUTION_FAILED | An OpenAPI tool call fails during HTTP execution. | — |
ACCOUNT_INVALID | An account entry, label, provider, or provider-specific configuration is invalid. | — |
ACCOUNT_NOT_FOUND | An account operation references a label that is not registered. | — |
ACCOUNT_DUPLICATE_LABEL | An account add operation would create a duplicate label without replace enabled. | — |
ACCOUNTS_FILE_INVALID | The accounts.json file is not valid JSON or does not match the expected account registry schema after tolerant entry filtering. | — |
"provider": "gemini" subscription is skipped with a warning that names the
account label and valid providers, while the remaining valid accounts still
load. ACCOUNTS_FILE_INVALID is reserved for invalid JSON or entries whose
known provider shape is malformed.
HTTP API Errors
JSON response codes, notSmithersErrorInstance objects.
| Code | Status | When |
|---|---|---|
INVALID_REQUEST | 400 | Invalid request body or query params |
PAYLOAD_TOO_LARGE | 413 | Body exceeds maxBodyBytes |
INVALID_JSON | 400 | Body not valid JSON |
SERVER_ERROR | 500 | Unexpected server error |
UNAUTHORIZED | 401 | Missing or invalid auth token |
WORKFLOW_PATH_OUTSIDE_ROOT | 400 | Workflow path outside server root |
RUN_ID_REQUIRED | 400 | runId required when resume: true |
RUN_ALREADY_EXISTS | 409 | Run ID already exists |
RUN_NOT_FOUND | 404 | No run with given ID |
RUN_NOT_ACTIVE | 409 | Run not active (cannot cancel) |
NOT_FOUND | 404 | Route or resource not found |
DB_NOT_CONFIGURED | 400 | Server database not configured |