Errors Reference

Purpose and Scope

Flue's public transports expose errors as a caller-safe contract, not as raw exceptions from the runtime. This page explains that contract so API clients, frontends, command wrappers, and integration code can make stable decisions when a request fails. The most important rule is to branch on the machine-readable error type, not on the human-facing message text. Messages and details are meant to help a person understand the failure, while the type is the durable value applications should use for control flow.

Sources: apps/docs/src/content/docs/api/errors-reference.md

The errors reference also draws a boundary between transport failures and other failure surfaces. Runtime operations, workflow records, CLI commands, development servers, and builds can all report failures, but not all of those reports use the same public transport vocabulary. Treat this page as the reference for framework-owned HTTP and transport envelopes. For lower-level diagnostics, preserve the public error when one is provided, then consult the relevant runtime, routing, persistence, workflow, or CLI page for the surface that produced it.

A Flue error response is intentionally conservative. Unknown server failures are converted to an internal error shape so callers do not receive private exception messages, stack traces, secrets, or implementation-specific database information. Local development can include additional guidance through a separate field, but preview and production builds omit local-only help. This keeps production responses safe while still giving developers actionable hints when running a temporary local server or development runtime.

Relevant Source Files

  • apps/docs/src/content/docs/api/errors-reference.md — Defines the reader-facing FluePublicError shape, the stable public transport categories, the local-only development guidance behavior, and the distinction between transport errors and other runtime or build failures.

Public Transport Error Shape

The public error payload is named FluePublicError. It contains a stable type, a short message, a more explanatory details string, and optional dev and meta fields. The required fields are intended for every caller. The optional fields exist for situations where the runtime can safely expose extra context: dev adds local development guidance, while meta carries structured machine-readable details such as validation issues. A client should be prepared for both optional fields to be absent.

interface FluePublicError {
  type: string;
  message: string;
  details: string;
  dev?: string;
  meta?: Record<string, unknown>;
}

The distinction between message and details matters when designing integrations. A toast notification, log summary, or command-line status line can use message. A troubleshooting panel can show details. Automated behavior should inspect type, and validation-aware clients can inspect meta when present. Do not parse the prose in message or details; those strings are caller-facing explanations, while the category is the API contract. This lets Flue improve wording without breaking applications that handle errors programmatically.

The dev field is deliberately environment-sensitive. It is omitted unless Flue has additional guidance and the runtime is local. Temporary local flue run runtimes use local rendering on Node.js and in Cloudflare's Vite or workerd development runtime. If flue run attaches to an absolute --server, the response envelope is whatever that server returns. Preview and production builds omit local-only guidance, so production clients should never require dev to exist in order to handle a failure.

Stable Categories and HTTP Statuses

The following categories are stable for framework-owned transport failures. HTTP responses use the listed status code, and method failures include the protocol-appropriate Allow header. These categories cover validation, routing, resource lookup, workflow stream lookup, unavailable run storage, and generic server failures. The table is the compact reference to use when writing clients, tests, or middleware that normalize Flue API failures into application-specific error handling.

TypeHTTP statusMeaning
method_not_allowed405The endpoint does not accept the request method. HTTP responses include Allow.
unsupported_media_type415A request body was not sent as JSON.
invalid_json400A request body could not be read or parsed as JSON.
agent_not_found404The requested agent is not registered or not exposed through the requested transport.
workflow_not_found404The requested workflow is not registered or not exposed over HTTP.
route_not_found404No generated default-application route matches the request.
run_not_found404The workflow run is missing, expired, or not owned by the resolved workflow instance.
stream_not_found404The agent-instance event stream does not exist yet; agent streams are created on first admitted prompt.
run_store_unavailable501The runtime does not provide workflow-run storage, lookup, or listing.
invalid_request400The request shape, parameters, or protocol message is invalid. Read details for the specific reason.
internal_error500An unknown or non-public server failure occurred.

These categories are intentionally broad enough to remain stable while still being useful. For example, invalid_request can describe shape problems, parameter problems, or protocol message problems, so clients should read details and meta for the specific reason. By contrast, agent_not_found, workflow_not_found, and route_not_found distinguish different lookup failures that have different remedies: expose the resource, register the module, or correct the mounted route path. internal_error should be treated as retryable only if the calling workflow has its own retry policy.

Routing, Agents, and Workflow Failures

Routing-related errors usually mean the request reached Flue but did not match a published capability. A generated default application can return route_not_found when no route matches. Mounted applications can also expose only a subset of resources, so agent_not_found and workflow_not_found do not necessarily prove the source file does not exist; they mean the requested resource is not registered or not exposed through that transport. This is especially relevant when agent and workflow modules require explicit route exports before HTTP access is available.

Agent stream errors have their own nuance. stream_not_found means the event stream for an agent instance does not exist yet, and the reference explains that agent streams are created on the first admitted prompt. A client that subscribes before admission should handle this differently from an authorization failure or a missing agent. In practice, prompt submission should be the operation that establishes stream coordinates, and stream readers should use those coordinates rather than inventing them ahead of time.

Workflow run errors separate the workflow definition from a particular durable run. workflow_not_found points at the callable workflow surface. run_not_found points at an existing run resource and can mean that the run is missing, expired, or not owned by the resolved workflow instance. run_store_unavailable is different again: the runtime does not provide the storage needed for workflow-run storage, lookup, or listing. That category is a configuration or target capability problem rather than a bad run id.

Validation, JSON, and Media-Type Failures

Request-body errors are reported before Flue can safely interpret the payload. unsupported_media_type means the body was not sent as JSON, while invalid_json means the body could not be read or parsed as JSON. These are different remediation paths. The first is usually a missing or incorrect content type or transport format. The second is malformed bytes, truncated input, or JSON syntax that fails before schema validation can run. Clients should surface these distinctly because retrying the same payload will not fix either problem.

Once a request is JSON and parseable, Flue can still reject it as invalid_request. This category covers invalid request shape, parameters, or protocol messages. The details field should identify the specific issue, and meta may contain structured validation information when available. Validation-aware clients should preserve the whole error object, not just the type, so form UIs, SDK wrappers, and test assertions can show the exact problem while still relying on the stable category for branching.

Development Diagnostics and Safe Handling

The reference makes local diagnostics opt-in by environment rather than by caller. That design prevents production information leaks while keeping local development fast. When dev appears, show it to the developer or include it in local logs. When it does not appear, do not treat the response as incomplete. A production-safe error still contains type, message, and details, and unknown failures intentionally become internal_error without leaking their original exception message.

A robust handler should normalize the public shape once, then make decisions from the normalized object. For user-facing flows, display message and optionally expand details. For automation, branch on type. For validation UIs, inspect meta defensively. For observability, log the public payload along with request context, but avoid assuming that local dev text exists. For retries, distinguish bad input categories from lookup failures and internal failures before deciding whether to retry, prompt the user, or report a configuration issue.

function handleFlueError(error: FluePublicError) {
  switch (error.type) {
    case 'invalid_request':
      return { retry: false, reason: error.details, issues: error.meta };
    case 'run_store_unavailable':
      return { retry: false, reason: 'Workflow run storage is unavailable.' };
    case 'internal_error':
      return { retry: true, reason: error.message };
    default:
      return { retry: false, reason: error.message };
  }
}

Next Steps

Use this page when implementing API clients, SDK wrappers, frontend reducers, integration tests, or channel callbacks that need predictable failure behavior. Pair it with the Routing API when diagnosing route, agent, workflow, or channel lookup failures, and pair it with the Data Persistence API when diagnosing run storage availability. When debugging locally, read dev if it is present; when building production clients, treat the required fields and stable category table as the contract.