跳转到内容

输入关键词开始搜索文档。

错误参考

最后更新 查看 Markdown 源文件

类型化的框架失败是带有稳定机器可读 type 代码的 FlueError 子类,加上下面记录的两个普通 Error 类(AgentRunError 和 ResultUnavailableError)。取消以名为 AbortError 的 DOMException 拒绝。编程入口点的误用(在运行时配置之前调用 dispatch() 或 init()、空实例 ID)抛出普通 Error,其 [flue] 前缀的消息是说明文,不是 API。错误类从 @flue/runtime 导出,有两个例外:Cloudflare 绑定表面在 @flue/runtime/cloudflare 上,持久化存储类在 @flue/runtime/adapter 上。

Flue Agent SDK 的错误类(FlueApiError、FlueExecutionError、流错误)在 SDK 错误参考中有文档。它们包装本页定义的相同线路信封和结算形状。

FlueError

class FlueError extends Error {
  readonly type: string;
  readonly details: string;
  readonly dev: string;
  readonly meta: Record<string, unknown> | undefined;
  readonly cause: unknown;
}

框架类型化错误的基类。用 err instanceof FlueError 区分 Flue 失败和任意错误,然后用具体子类或 type 字段收窄。

  • type — 稳定的 snake_case 标识符,每个子类一个常量。这是机器可读的契约;在代码和遥测中匹配它。
  • message — 一句调用者安全的话。说明文,不是 API:消息字符串可能在版本间变化。
  • details — 更长的调用者安全说明文,关于请求和调用者可以做什么。始终在线路上渲染。当类没有更多可说的时为 ''。
  • dev — 面向开发者的说明文:可用替代方案、文件系统布局、源级修复指令。仅在本地开发中在线路上渲染。当类没有特定于开发的内容时为 ''。
  • meta — 可选的结构化数据。仅由记录为携带它的子类设置;设置时在每种模式下都包含在线路上。
  • cause — 包装时的底层错误。服务端记录;从不在线路上发送。
  • name — 不是判别器。大多数子类报告 'FlueError' 或 'FlueHttpError';只有少数覆盖它。使用 instanceof 或 type。

HTTP 基类(FlueHttpError,添加 readonly status: number 和 readonly headers: Record<string, string> | undefined)不导出。它的两个导出子类 AgentInstanceNotFoundError 和 AgentInstanceExistsError 通过它暴露 status 和 headers。

HTTP 错误信封

来自智能体路由、挂载的 createAgentRouter() 应用或频道路由器的每个错误响应携带一个 JSON 主体形状:

{
  "error": {
    "type": "stream_not_found",
    "message": "Event stream \"...\" was not found.",
    "details": "Streams are created when their agent instance receives its first prompt.",
    "dev": "...",
    "meta": {}
  }
}
  • type、message、details — 始终存在。
  • dev — 仅当服务器在本地开发中运行(flue dev、flue run)且错误类填充了它时存在。它的存在不是可靠的模式信号:类设置了 dev: '' 的错误在每种模式下都省略该字段。
  • meta — 无论错误类是否设置它,在开发和生产中都存在。
  • ref — 服务器铸造的关联引用(err_ + ULID),仅当服务器记录了错误时存在(下面的两个 500 类渲染)。相同值作为 flue-error-ref 响应头发送,并前缀匹配的服务端日志行。在未记录的调用者错误(4xx)响应上从不出现。
  • cause 和堆栈跟踪——从不出现。

状态解析:

  • HTTP 类型的 FlueError 用其类拥有的状态(下面按类型列出)加上任何类拥有的头(405 上的 Allow、503 上的 Retry-After: 1)渲染。
  • 逃逸到路由的非 HTTP FlueError 用状态 500 渲染其类型化信封并在服务端记录,新的 ref 将响应与日志行关联。
  • 任何非 FlueError 的抛出值渲染为通用 500 internal_error 信封。原始错误在服务端完整记录,除了 ref 之外没有任何内容到达线路。

每个错误响应还携带 content-type: application/json、x-content-type-options: nosniff 和 cross-origin-resource-policy: cross-origin。

两个路由响应刻意省略信封:HEAD 对话读取仅用状态和头回答错误(无主体——flue-error-ref 头在记录的渲染上仍然存在),客户端中止的长轮询读取返回状态 499 和空主体。SSE 或长轮询头发送后的中途失败在没有信封的情况下终止流。

关联生产环境 500 错误

引用 ref(来自 error.ref 或 flue-error-ref 头——该头在无主体响应和吞没主体的中介中存活)。匹配的服务端日志行以 [flue] [err_…] 开头并携带完整错误及其原因链和堆栈;因为 ref 是 ULID,单独的 ref 也界定了搜索的时间窗口。当失败的请求携带了 W3C traceparent 时,日志行在 ref 旁边记录它,因此传播跟踪上下文的调用者可以将失败加入自己的跟踪。ref 仅存在于同步渲染中:在 202 接纳之后失败的提交没有 ref——它的句柄是 submissionId,由 submission_settled 记录、SDK 的 FlueExecutionError.targetId 和相应的 [flue:submission-…] 日志行共享。

路由错误类型

智能体路由产生的线路 type 代码及其状态。只有 agent_instance_not_found 和 agent_instance_exists 有可导入的类;其余在 error.type 上匹配。路由本身在流协议参考中有文档。

  • invalid_request — 400。畸形请求:错误的 URL 或参数形状、空的 instance-id 段、无效的调度载荷、uid 条件与 initialData 结合,或创建数据未通过智能体的 initialDataSchema。details 说明具体原因。
  • invalid_json — 400。请求主体存在但无法解析为 JSON。details 包含解析器的报告。
  • unsupported_media_type — 415。请求主体存在但没有 Content-Type: application/json 头。
  • method_not_allowed — 405。响应携带 Allow 头列出接受的方法。
  • route_not_found — 404。没有路由匹配方法和路径。已注册的路由不会被枚举。
  • stream_not_found — 404。对从未接收过提示的实例的对话流读取。
  • attachment_not_found — 404。未知的附件 ID,或属于非默认对话的附件。
  • history_cursor_not_found — 410。有界历史读取的 before 或 from 游标由早期一代对话流发出(流已被重置并重新增长),或指向已消失的消息。在 meta.cursor 中携带被拒绝的游标。不带游标重新读取最新窗口。
  • agent_instance_not_found — 404。参见 AgentInstanceNotFoundError。
  • agent_instance_exists — 409。参见 AgentInstanceExistsError。
  • runtime_unavailable — 503。本地开发运行时正在重新加载、排空或加载失败。携带 Retry-After: 1 和 meta.state('loading' | 'draining' | 'failed');在开发模式下 dev 携带底层加载失败。
  • internal_error — 500。意外服务器错误的通用编辑。

发送的接纳——通过 HTTP 或通过 dispatch() 和 init().dispatch()——也以 type: 'invalid_request' 拒绝载荷误用:uid 字符串条件与 initialData 结合、创建数据未通过智能体的 initialDataSchema,或非函数的 agent 参数。该类(InvalidRequestError)不导出;用 instanceof FlueError 和 type 字段匹配。

内部不变量和持久化失败有自己的代码,可以出现在 500 信封或结算错误中:conversation_record_invariant(无可导入类)、@flue/runtime/adapter 类携带的存储代码(AttachmentConflictError、AttachmentIntegrityError、ConversationStreamStoreError、PersistedFormatVersionError),以及 cloudflare_ai_binding_error(@flue/runtime/cloudflare 上的 CloudflareAIBindingError)。

app.ts 中编写的路由和中间件拥有自己的响应;上面的信封和状态词汇仅适用于框架拥有的路由。

AgentInstanceExistsError

class AgentInstanceExistsError extends FlueError {
  // type: 'agent_instance_exists', status: 409
  readonly uid: string | undefined;
}

仅创建发送(uid: null)——带有条件的 dispatch() 或 init().dispatch(),或等效的 HTTP 主体字段——命名了已存在的实例。在接纳时同步抛出;触发时不创建任何持久内容。通过 HTTP 以状态 409 渲染;编程上返回的 promise 以类实例拒绝。

  • uid — 现有 incarnation 的 uid,可直接用作继续条件。对于 uid 发布之前创建的实例为 undefined。uid 也作为 meta.uid 在线路信封上(并出现在 details 说明文中),因此 HTTP 调用者可以继续现有实例而无需单独查找。

AgentInstanceNotFoundError

class AgentInstanceNotFoundError extends FlueError // type: 'agent_instance_not_found', status: 404

仅继续发送(uid: '<string>')——带有条件的 dispatch() 或 init().dispatch(),或等效的 HTTP 主体字段——命名了不存在或 uid 不匹配的实例。两种情况产生相同的错误:对持有 uid 条件的调用者来说,已知的 incarnation 无论如何都不存在。在接纳时同步抛出;触发时不创建任何持久内容。通过 HTTP 以状态 404 渲染;编程上返回的 promise 以类实例拒绝。不带 uid 发送以无条件投递。

也是对指向不存在实例的 init().read() 的拒绝:读取等待结算,从未联系过的实例没有可结算的内容,因此未命中快速失败而不是永远等待。

AgentRunError

class AgentRunError extends Error {
  readonly outcome: 'failed' | 'aborted';
  readonly submissionId: string;
}

等待的 init().read() 调用的拒绝,其提交结算为 failed 或 aborted。不是 FlueError。

  • outcome — 非完成的结算结果。
  • submissionId — 已结算的提交。
  • cause — 结算的序列化错误(结算错误形状下的 { name?, message, type?, details?, meta? } 形状),当结算携带一个时。

signal 已触发的 read() 调用以信号的原因而非 AgentRunError 拒绝——默认是名为 AbortError 的 DOMException。这仅是读取的本地取消;提交本身继续运行并独立结算。要持久停止智能体的工作,调用 abort()。

AttachmentConflictError

// from '@flue/runtime/adapter'
class AttachmentConflictError extends FlueError // type: 'attachment_conflict'

附件 ID 被不同内容、元数据或所有权重用。从 @flue/runtime/adapter 导出,与它保护的存储契约一起;参见数据持久化 API。在存储操作中触发,不是 HTTP 类别;逃逸到路由的以 500 渲染并带有自己的类型代码。meta 携带 path 和 attachmentId。

AttachmentIntegrityError

// from '@flue/runtime/adapter'
class AttachmentIntegrityError extends FlueError // type: 'attachment_integrity'

附件字节未通过完整性验证。从 @flue/runtime/adapter 导出,与它保护的存储契约一起;参见数据持久化 API。在存储操作中触发,不是 HTTP 类别;逃逸到路由的以 500 渲染并带有自己的类型代码。meta 携带 attachmentId 和 reason('size' | 'digest' | 'chunks')。

AttachmentNotAvailableError

class AttachmentNotAvailableError extends FlueError // type: 'attachment_not_available'

当委派的任务引用了调用会话对话中不可见的附件 ID 时,由 harness 操作抛出。meta 携带 attachmentId。

CloudflareAIBindingError

// from '@flue/runtime/cloudflare'
class CloudflareAIBindingError extends FlueError {
  // type: 'cloudflare_ai_binding_error'
  constructor(options: { message?: string; status?: number; statusText?: string; body?: string });
}

Workers AI 绑定请求失败。从 @flue/runtime/cloudflare 导出;特定于 Workers AI 绑定路径,不在根桶中。Provider 响应主体在 message(限制为 2000 字符)以及 details 中,因为重试和溢出分类读取持久化的助手错误消息。meta 携带 status 和 statusText(当已知时),加上 413 响应上的 reason: 'request_too_large',以便遥测可以区分自愈上下文溢出和绑定中断。构造函数是公开的,因此应用可以在针对安装的运行时的回归测试中构建实例。

ConversationStreamStoreError

// from '@flue/runtime/adapter'
class ConversationStreamStoreError extends FlueError // type: 'conversation_stream_store_failure'

规范对话流操作被拒绝;流保持不变。从 @flue/runtime/adapter 导出,与它保护的存储契约一起;参见数据持久化 API。在存储操作中触发,不是 HTTP 类别;逃逸到路由的以 500 渲染并带有自己的类型代码。meta 携带 operation、path 和 reason。

相关的 conversation_record_invariant 代码(违反流契约的持久化对话记录)没有导出类。

DelegationDepthExceededError

class DelegationDepthExceededError extends FlueError // type: 'delegation_depth_exceeded'

当嵌套的 task() / harness 工具委派链超过最大深度时,由 harness 操作抛出。message 包含限制。

InstrumentationAlreadyInstalledError

class InstrumentationAlreadyInstalledError extends FlueError // type: 'instrumentation_already_installed'

在同类检测所有者活跃时调用了 instrument()。先处理活跃的那个。

OperationFailedError

class OperationFailedError extends FlueError // type: 'operation_failed'

harness 操作——FlueHarness 和 FlueSession 上的 prompt()、skill()、task()、shell() 或 compact()——运行了但未完成:底层模型调用出错,或持久输入无法持久化或恢复。meta 携带 operation 和 reason(解包装的失败文本,也嵌入在 message 中;两者都是说明文,不是 API)。

PersistedFormatVersionError

// from '@flue/runtime/adapter'
class PersistedFormatVersionError extends FlueError // type: 'persisted_format_version_unsupported'

数据库记录了此运行时不支持的格式版本:由更新的 Flue 版本标记(回滚后)或携带无法识别的版本标记。在打开存储时抛出,在启动时。从 @flue/runtime/adapter 导出,与它保护的存储契约一起;参见数据持久化 API。meta 携带 storedVersion 和 supportedVersion。

ResultUnavailableError

class ResultUnavailableError extends Error {
  readonly reason: string;
  readonly assistantText: string;
}

当调用设置了 options.result 且模型调用了框架的放弃工具而不是产生符合模式的数据时,由 prompt()、skill() 和 task() 抛出。不是 FlueError。

  • reason — 模型提供的解释。
  • assistantText — 放弃前积累的助手对话记录。

SandboxOperationUnsupportedError

class SandboxOperationUnsupportedError extends FlueError // type: 'sandbox_operation_unsupported'

沙盒适配器在修改文件系统之前拒绝了它不实现的操作或选项集。meta 携带 operation、provider 和 options。参见沙盒 API 参考。

SessionBusyError

class SessionBusyError extends FlueError // type: 'session_busy'

harness 操作——prompt()、skill()、task()、shell() 或 compact()——在会话已在运行一个时被调用。会话一次运行一个操作;为并行分支打开另一个会话。

SessionNotFoundError

class SessionNotFoundError extends FlueError // type: 'session_not_found'

harness 内部的会话查找失败。公共 harness 操作获取或创建默认会话,不会命中它。

SkillDefinitionValidationError

class SkillDefinitionValidationError extends FlueError // type: 'skill_definition_validation'

defineSkill() 接收到了无效的定义。meta.issues 携带 ValidationIssue[]。

SkillNotRegisteredError

class SkillNotRegisteredError extends FlueError // type: 'skill_not_registered'

skill(name) 命名了初始化时在会话沙盒中未发现的技能。从 SKILL.md 导入的打包技能引用绕过发现。

SubagentNotDeclaredError

class SubagentNotDeclaredError extends FlueError // type: 'subagent_not_declared'

task({ agent }) 命名了智能体声明中不存在的子智能体。

SubmissionAbortedError

class SubmissionAbortedError extends FlueError // type: 'submission_aborted'

持久提交结算的终端错误:它成为 submission_settled 记录和事件的 error(下面的结算错误形状)并拒绝等待的结算观察者(init().read()、SDK 的 wait())。实例的工作被中止(路由的 POST .../abort,或 init() 句柄的 abort())。中止停止实例的所有进行中和排队工作。中止是不同的终端结果,不是失败:已提交其终端记录的提交从不被中止,输掉完成响应竞赛的中止结算为完成。

SubmissionInterruptedError

class SubmissionInterruptedError extends FlueError // type: 'submission_interrupted'

持久提交结算的终端错误:它成为 submission_settled 记录和事件的 error(下面的结算错误形状)并拒绝等待的结算观察者(init().read()、SDK 的 wait())。在提交的输入应用之前,每次处理尝试都被中断(进程崩溃、重启、关闭);共享的尝试预算在从未开始模型调用的情况下耗尽。它反映了智能体的 durability 配置;参见持久性指南了解尝试和超时模型。meta 携带 phase: 'retry_exhausted_before_input'、attemptCount 和 maxAttempts。

SubmissionRetryExhaustedError

class SubmissionRetryExhaustedError extends FlueError // type: 'submission_retry_exhausted'

持久提交结算的终端错误:它成为 submission_settled 记录和事件的 error(下面的结算错误形状)并拒绝等待的结算观察者(init().read()、SDK 的 wait())。恢复在输入应用后重新尝试了被中断的提交,直到 durability.maxAttempts 耗尽且没有完成的响应;参见持久性指南了解尝试和超时模型。当终端化结算了其结果无法确认的工具调用时,meta.interruptedTools 将它们列为 { name, id } 对;每个在对话中都有明确的中断错误结果,从未被假定为完成或重试。meta 还携带 attemptCount 和 maxAttempts。

SubmissionTimeoutError

class SubmissionTimeoutError extends FlueError // type: 'submission_timeout'

持久提交结算的终端错误:它成为 submission_settled 记录和事件的 error(下面的结算错误形状)并拒绝等待的结算观察者(init().read()、SDK 的 wait())。提交超过了 durability.timeoutMs;参见持久性指南了解尝试和超时模型。

ToolInputValidationError

class ToolInputValidationError extends FlueError // type: 'tool_input_validation'

模型提供的参数未通过工具的 input 模式。在模型轮次期间,它成为交付回模型的错误工具结果——提交继续,消息面向模型,模型可能更正参数并再次调用;在模型轮次之外,错误传播到调用者。meta 携带 tool 和 issues。

ToolNameConflictError

class ToolNameConflictError extends FlueError // type: 'tool_name_conflict'

工具列表包含重复名称,或自定义或适配器工具使用了框架保留的名称。在会话组装工具时抛出,在任何模型调用之前。参见工具指南了解编写表面。

ToolOutputSerializationError

class ToolOutputSerializationError extends FlueError // type: 'tool_output_serialization'

工具的返回值不可 JSON 序列化,或工具声明了 output 模式但返回了 undefined。在模型轮次期间,它成为交付回模型的错误工具结果——提交继续;在模型轮次之外,错误传播到调用者。meta 携带 tool;当存在时 cause 携带序列化失败。

ToolOutputValidationError

class ToolOutputValidationError extends FlueError // type: 'tool_output_validation'

工具的返回值未通过其 output 模式。在模型轮次期间,它成为交付回模型的错误工具结果——提交继续;在模型轮次之外,错误传播到调用者。meta 携带 tool 和 issues。

ValidationIssue

interface ValidationIssue {
  readonly message: string;
  readonly path?: readonly PropertyKey[];
}

type ToolValidationIssue = ValidationIssue;

Standard Schema 问题形状中的一个验证失败;path 段是通向失败值的属性键。由上面的验证错误在 meta.issues 中携带。

结算错误形状

submission_settled 事件、持久结算记录和 submission-settled 对话流块携带结果,对于 failed 和 aborted,携带序列化错误:

{
  type: 'submission_settled';
  submissionId: string;
  outcome: 'completed' | 'failed' | 'aborted';
  error?: {
    name?: string;
    message: string;
    type?: string;
    details?: string;
    dev?: string;
    meta?: Record<string, unknown>;
  };
}

FlueError 用其 name、message、type、details 和 meta 序列化。任何其他失败原因被编辑为通用 internal_error 条目——非 Flue 错误消息从不到达结算记录或线路。结算错误从不携带堆栈。

WORKERS_AI_OVERFLOW_MARKER 和 RETRYABLE_INTERRUPTION_MARKER

const WORKERS_AI_OVERFLOW_MARKER = '(request_too_large)';
const RETRYABLE_INTERRUPTION_MARKER = '(retryable_interruption)';

在没有类型化错误对象存活的地方使用的消息字符串标记——分类读取持久化的助手错误消息。

  • WORKERS_AI_OVERFLOW_MARKER — 附加到绑定 413 错误消息;压缩层匹配它以触发上下文溢出恢复(压缩并重试)。
  • RETRYABLE_INTERRUPTION_MARKER — 仅由能证明失败是瞬态中断的抛出站点标记(例如 Workers AI 流在没有错误帧或完成原因的情况下结束);重试分类在回退到消息模式启发式之前匹配它。

暴露 Provider 错误的应用可以匹配或剥离这些标记。它们的字符串值就是契约。

实时观测上的 errorInfo

交付给进程内 observe() 订阅者的 FlueObservation 值在失败活动上携带分类的错误详情。字段的形状(接口本身不导出):

// FlueObservation
errorInfo?: {
  type: string;
  name?: string;
  code?: string;
  message?: string;
  meta?: Record<string, unknown>;
  stack?: string;
};

分类规则,应用于抛出的值:

  • 名为 AbortError 的 DOMException → type: 'AbortError'。
  • FlueError → type 是错误的稳定代码;meta 是错误的框架拥有的元数据(例如验证问题),因此观察者获得结构化的失败详情而无需解析消息。
  • 任何其他对象 → type 是其字符串 type,否则 code,否则 name,否则 '_OTHER';当它们是字符串时携带 name、code 和 message。
  • 字符串 → { type: '_OTHER', message };其他 → { type: '_OTHER' }。
  • stack — 抛出站点堆栈,仅当失败是从真实的 Error 实例实时观察到时存在,从不从任意抛出对象。

errorInfo 出现在失败的 tool 观测、失败的 operation 观测和非完成的 submission_settled 观测上。调用者驱动的 shell() bash 工具的失败仅分类到 type/name/message 子集,没有 meta 或 stack。errorInfo 仅限进程内:operation 和 compaction 事件上的持久化形状的 error 字段序列化为 { name, message }(加上 FlueError 的 type、details、meta),持久化记录从不携带 stack——堆栈暴露文件系统路径和部署布局,因此它们远离任何持久化、重放或通过 HTTP 发送的内容。参见事件参考了解观测类型和可观测性指南了解订阅者设置。

轮次错误规范化

模型调用失败不会抛穿智能体渲染。它们规范化为 turn 事件的 response,当提交无法恢复时,以 OperationFailedError 或持久提交错误结算提交。

// turn event
{
  type: 'turn';
  turnId: string;
  purpose: 'agent' | 'compaction' | 'compaction_prefix';
  durationMs: number;
  request: ModelRequestInfo;
  response: ModelResponse;
  isError: boolean;
}

interface ModelResponse {
  responseId?: string;
  responseModel?: string;
  output?: LlmAssistantMessage;
  usage?: PromptUsage;
  finishReason?: string;
  providerFinishReason?: string;
  gatewayLogId?: string;
  error?: /* 上面的 errorInfo 形状 */;
}
  • finishReason — 规范化的完成词汇:'stop'、'length'、'toolUse'、'error' 或 'aborted'。每个 Provider 的原生完成值映射到此集合。
  • providerFinishReason — Provider 规范化前的确切完成值(例如 Workers AI tool_calls 在规范化 toolUse 之后)。仅遥测;从不是重放或执行身份的一部分。
  • gatewayLogId — 响应级 Cloudflare AI Gateway 日志关联(cf-aig-log-id),从响应自身的头读取,因此并发请求无法交叉归因。仅遥测。
  • error — 分类的错误,当请求抛出或助手消息携带 Provider 错误消息时存在。裸 Provider 错误字符串分类为 type: '_OTHER',文本在 message 中。
  • isError — 当请求抛出或 finishReason 为 'error' 或 'aborted' 时为 true。

边界

  • type 字符串是稳定的机器契约。message、details 和 dev 说明文可能在版本间变化;不要解析它们。
  • 没有导出的错误代码枚举或列表;代码在类上和本页上。
  • 没有按 Provider 的错误层次结构。Provider 失败规范化为轮次结果,最终为 operation_failed 或持久提交错误。唯一的 Provider 特定类是 CloudflareAIBindingError。
  • 取消从不是 FlueError:中止的操作和调度以名为 AbortError 的 DOMException 拒绝。
  • 线路从不携带 cause、堆栈或非 Flue 错误消息;三者都留在服务端日志中。
  • CLI、配置和构建诊断(flue 命令、flue.config.* 验证、Vite 插件)是面向人类的 stderr 说明文,没有稳定的机器可读代码。
  • 在编写的 app.ts 中的应用拥有的路由和中间件返回它们选择的任何状态和主体;Flue 不对它们强加信封或类别(例如没有 unauthorized 类型)。