> ## Documentation Index
> Fetch the complete documentation index at: https://firecrawl-docs-remove-capabilities-from-sidebar.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 错误

> 所有 API 错误代码、成因、处理方法，以及是否应重试。

每个 Firecrawl 错误响应都采用相同的 JSON 结构。请在下表中查找 `error` 的值 (或 HTTP 状态码) ，以了解错误原因、处理方法，以及该请求是否可以安全重试。

<Note>本文涵盖了大多数代理和客户端会遇到的错误，但并非完整列表——如果你遇到了此处未列出的错误，请[提交 issue](https://github.com/firecrawl/firecrawl/issues)，以便我们将其补充到文档中。</Note>

<div id="error-response-shape">
  ## 错误响应结构
</div>

所有非 2xx 响应都会返回 JSON，顶层包含 `success: false` 和字符串类型的 `error`。某些端点在可提供更多上下文信息时，还会包含其他字段 (`details`、`code`) 。

```json theme={null}
{
  "success": false,
  "error": "Unauthorized: Invalid token",
  "details": "Optional structured details (only present on some errors)"
}
```

| 字段 | 类型 | 描述 |
| - | - | - |
| `success` | `boolean` | 出错时始终为 `false`。 |
| `error` | `string` | 便于人工阅读的错误消息。可据此查找下方对应的行。 |
| `details` | `any` | 可选。适用时，包含按字段组织的结构化验证错误信息。 |

<div id="errors">
  ## 错误
</div>

| HTTP | `error` (典型消息) | 原因 | 处理方法 | 可重试 |
| - | - | - | - | - |
| 400 | `Bad Request` / 验证消息 | 请求体未通过 schema 验证 (字段缺失或无效) 。 | 根据 端点 参考文档修正请求 payload。检查 `details` 中的字段。 | 否 |
| 400 | `Invalid URL` | `url` 字段缺失、格式错误，或使用了不受支持的协议。 | 传入绝对 `http(s)://` URL。 | 否 |
| 401 | `Unauthorized: Invalid token` | API 密钥缺失、格式错误或已被撤销。 | 发送 `Authorization: Bearer fc-...`，并使用 [Dashboard](https://www.firecrawl.dev/app/api-keys) 中的有效密钥。 | 否 |
| 402 | `Payment Required: Insufficient credits` | 套餐额度已用尽，或尚未配置计费。 | 启用 pay-as-you-go，或升级你的套餐。 | 否 |
| 403 | `Forbidden` | 该密钥没有访问此 端点 或功能的权限。 | 使用具备所需 scope 的密钥，或升级包含该功能的套餐。 | 否 |
| 403 | `SCRAPE_PROMPT_INJECTION_DETECTED` | 启用 `checkPromptInjection: true` 的 JSON 模式在抓取的页面内容中检测到 prompt 注入尝试，因此中止了提取。 | 手动检查页面内容。如果是误报，请在不使用 `checkPromptInjection` 的情况下重试。请参见 [Prompt 注入检测](/zh/features/llm-extract#prompt-injection-detection)。 | 否 |
| 404 | `Not Found` | 任务 ID、资源或 端点 路径不存在。 | 核实资源 ID 和 端点 URL。 | 否 |
| 408 | `Request Timeout` | 页面加载时间超过了请求 `timeout`。 | 增加 `timeout`、简化 actions，或使用 `fastMode`。 | 是，需退避重试 |
| 409 | `Conflict` | 资源当前所处状态阻止了该操作 (例如已被删除) 。 | 重试前重新获取状态并完成协调。 | 否 |
| 413 | `Payload Too Large` | 请求体超过允许的最大大小。 | 缩减 payload (例如缩短 schema、减少每个 batch 中的 URL 数量) 。 | 否 |
| 422 | `Unprocessable Entity` / 提取 schema 错误 | schema 不是有效的 JSON Schema，或模型无法生成符合要求的结果。 | 验证 schema；放宽必填字段；尝试其他 `model`。 | 有时 |
| 429 | `Rate limit exceeded` | 请求次数超过了你的套餐每分钟限额。 | 退避，并在 `Retry-After` 指定的秒数后重试。请参见 [限流](/zh/rate-limits)。 | 是，需退避重试 |
| 429 | `Concurrency limit reached` | 已达到你的套餐并发浏览器数上限。 | 等待进行中的任务完成、降低并发，或升级你的套餐。 | 是，需退避重试 |
| 500 | `Internal Server Error` | 服务端发生了未处理的故障。 | 使用指数退避重试。如果问题持续存在，请附上请求 ID 联系支持团队。 | 是，需退避重试 |
| 502 | `Bad Gateway` | 上游代理或工作进程返回了无效响应。 | 退避后重试。 | 是，需退避重试 |
| 503 | `Service Unavailable` | 服务暂时无法处理该请求。 | 退避后重试。 | 是，需退避重试 |
| 504 | `Gateway Timeout` | 请求超过了网关超时时间 (通常见于长时间爬取) 。 | 改用异步爬取/batch 端点，并改为轮询状态。 | 是，需退避重试 |

对于 429 响应，Firecrawl 会在可用时包含 `Retry-After` 响应标头 (单位为秒) ——重试前至少等待这么久。

<div id="agent">
  ## 代理
</div>

[`/agent`](/zh/features/agent) 及其状态、执行追踪、快照和取消端点特有的错误。执行追踪和快照端点会原样转发上游错误正文，因此这两个端点返回的正文可能不包含上述 `success` 字段；请根据 HTTP 状态码和 `error` 字符串进行判断。

| HTTP | `error` (典型消息) | 原因 | 解决方法 | 可重试 |
| - | - | - | - | - |
| 400 | `Invalid job ID format. Job ID must be a valid UUID.` | `jobId` 路径段不是有效的 UUID。 | 传入 `POST /v2/agent` 返回的 `id`。 | 否 |
| 400 | `Invalid snapshot ID` | `snapshotId` 路径段格式不正确。 | 使用 `artifact.updated` [执行追踪事件](/zh/api-reference/endpoint/agent-trace)中的 `snapshotId`。 | 否 |
| 400 | `Trace is only available for Spark 2 extracts` | 该任务早于 Spark 2，只有 Spark 2 会记录执行追踪。 | 此任务无需处理。所有新运行都会在 `spark-2` 上执行，并生成执行追踪。 | 否 |
| 400 | `Snapshots are only available for Spark 2 extracts` | 该任务早于 Spark 2，只有 Spark 2 会记录快照。 | 此任务无需处理。所有新运行都会在 `spark-2` 上执行，并生成快照。 | 否 |
| 400 | `Your team has zero data retention enabled. This is not supported on extract.` | 对于强制启用零数据保留的团队，无法提供代理运行。 | 联系 [support@firecrawl.com](mailto:support@firecrawl.com)，为你的团队解除此功能限制。 | 否 |
| 404 | `Agent job not found` | 该任务 ID 不存在，或属于其他团队。 | 检查任务 ID，并使用启动该运行的团队的密钥。 | 否 |
| 404 | `Snapshot not found` | 此任务没有具有该 ID 的快照。 | 重新获取执行追踪，并使用 `artifact.updated` [执行追踪事件](/zh/api-reference/endpoint/agent-trace)中当前的 `snapshotId`。 | 否 |
| 409 | `Agent already finished` | 对已到达终态的运行调用了取消操作。 | 请改为轮询 `GET /v2/agent/{jobId}` 获取结果。 | 否 |
| 409 | `Agent is already cancelled` | 对已处于取消中的运行调用了取消操作。 | 轮询 `GET /v2/agent/{jobId}`。已取消的运行会报告 `failed`，并附带取消消息。 | 否 |
| 500 | `Failed to passthrough agent request.` | 代理服务在提交时拒绝了该任务。 | 采用退避策略重试。如果问题持续存在，请携带请求 ID 联系支持团队。 | 是，采用退避策略 |

达到 `maxCredits` 上限的运行不会返回 HTTP 错误，而是会以失败任务结束。轮询状态端点会返回 `status: "failed"`、额度限制错误消息、无 `data`，以及 `creditsUsed: 0`，因为失败的运行不会计费。在执行追踪中，同一结果会显示为 `run.finished` 事件，其中 `outcome: "credit_limit_reached"`。

<div id="trace-error-codes">
  ### 执行追踪错误代码
</div>

终止事件和 `error.occurred` 执行追踪事件都会携带一个结构化的 `error` 对象，其 `code` 取值为以下五种之一。每个事件还会携带一个 `retryable` boolean，应按与上方**可重试**列相同的方式处理。

| `code` | 含义和处理方法 |
| - | - |
| `cancelled` | 你取消了此次运行。如需重新完成该工作，请启动新的运行。 |
| `credit_limit_reached` | 此次运行达到了 `maxCredits` 上限。请提高 `maxCredits`，或缩小 prompt 范围以减少所需工作量。 |
| `parent_finished` | 子代理停止运行，因为启动它的代理先完成了。请查看父代理自身的终止事件，了解实际原因。 |
| `refused` | 代理拒绝执行该任务。请重新表述 prompt，或将其范围限定为你有权采集内容的 URL。 |
| `internal` | 运行内部发生意外故障。请重试此次运行；若问题仍然存在，请携带任务 ID 联系支持团队。 |

<div id="retry-guidance">
  ## 重试指南
</div>

以 **可重试** 列为准；不要仅凭 HTTP 状态码自行判断。以下模式使用带抖动的指数退避，并在遇到 429 时遵循 `Retry-After`。

<CodeGroup>
  ```python Python theme={null}
  import time
  import random
  import requests

  RETRYABLE_STATUSES = {408, 429, 500, 502, 503, 504}

  def request_with_retry(method, url, headers=None, json=None, max_attempts=5):
      for attempt in range(max_attempts):
          resp = requests.request(method, url, headers=headers, json=json)
          if resp.status_code < 400 or resp.status_code not in RETRYABLE_STATUSES:
              return resp
          # 存在 Retry-After 时优先遵循，否则使用带抖动的指数退避。
          retry_after = resp.headers.get("Retry-After")
          delay = float(retry_after) if retry_after else min(2 ** attempt, 30) + random.random()
          time.sleep(delay)
      return resp
  ```

  ```js Node theme={null}
  const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);

  async function requestWithRetry(url, init = {}, maxAttempts = 5) {
    for (let attempt = 0; attempt < maxAttempts; attempt++) {
      const resp = await fetch(url, init);
      if (resp.ok || !RETRYABLE_STATUSES.has(resp.status)) return resp;
      // 存在 Retry-After 时优先遵循，否则使用带抖动的指数退避。
      const retryAfter = resp.headers.get('Retry-After');
      const delayMs = retryAfter
        ? Number(retryAfter) * 1000
        : Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000;
      await new Promise((r) => setTimeout(r, delayMs));
    }
  }
  ```

  ```bash cURL theme={null}
  # 针对可重试状态码使用指数退避的简单 shell 循环。
  attempt=0
  max=5
  until response=$(curl -sS -w "\n%{http_code}" -X POST "https://api.firecrawl.dev/v2/scrape" \
      -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"url":"https://example.com"}'); do
    status=$(printf '%s' "$response" | tail -n1)
    case "$status" in
      408|429|500|502|503|504)
        attempt=$((attempt+1))
        [ "$attempt" -ge "$max" ] && break
        sleep $((2 ** attempt))
        ;;
      *) break ;;
    esac
  done
  echo "$response"
  ```
</CodeGroup>

<div id="429-responses">
  ## 429 响应
</div>

429 响应是最常见的可重试错误。各套餐的限流和并发限制详见[限流](/zh/rate-limits)。如果存在 `Retry-After` 标头，请务必遵循其指定的等待时间，而不要立即重试。
