跳转至

故障排查

FAQ 格式:每条按 问题 → 原因 → 修复 组织。完整的错误语义参考(状态码、终态、 重试纪律)见响应与错误限流与错误

裸请求 API 遭遇 Cloudflare 403

问题:手工 curl / 脚本请求 www.perplexity.ai 的 REST 端点返回 403 和 Cloudflare 质询页——即使带上了从浏览器复制的 cookie——而同样的端点走工具却正常。

原因:Cloudflare 挡在站点前面,cf_clearance / __cf_bm 与浏览器的 TLS 指纹 绑定。裸客户端指纹不匹配,质询即触发。工具能过是因为用 Python urllib + 从浏览器 导入的 cookie + 桌面 Chrome User-Agentpplx_export/core/http/cookie_transport.py:29)。Cloudflare 在风控限流时也可能 403——那时响应带同样的质询形态。

修复

  • 不要绕过工具的 transport;用 pplx-export / pplx-ask 发起调用,不要写临时脚本。
  • 工具内部把 HTTP 200 但非 JSON 的响应体(Cloudflare 过场页)归类为传输错误而非数据 (pplx_export/core/http/cookie_transport.py:133)。
  • 工具内若开始出现 403,先放慢节奏(见限流)并刷新 cookie; 持续质询则需在浏览器里重新登录。
  • 注意 403 的两副面孔:Cloudflare 风控质询(放慢即可消退)与 API 级 403(cookie 失效——立即抛出、不退避,见下一节)。设计页映射的是后者 (rate-limiting-errors.md)。

背景:API 认证

问题:命令因鉴权错误失败——pplx-exportAuthTransportError: 鉴权失败 401, 或 pplx-ask ask 以 HTTP 401/403 的「更新 cookie」提示退出。

原因:会话 cookie 已过期或失效。401/403 被视为鉴权失败并立即抛出——不退避, 因为退避无法自愈死掉的会话(pplx_export/core/http/cookie_transport.py:82pplx_export/core/errors.py:68)。batch 在连续 3 次鉴权失败后还会 fail-fast, 避免死 cookie 烧穿整个队列。

修复

  1. 在浏览器里重新登录(或重新打开站点),让会话 cookie 续期。
  2. 刷新工具的 cookie 缓存。<out>/index/.cookies.json 在 12 小时新鲜期内会被复用 (pplx_export/core/cookies.py:39),所以重新登录后二选一:
  3. --cookies-from <browser> 跑一次,强制从浏览器重新导入;或
  4. 删除 <out>/index/.cookies.json,让下次运行自动重新导入。
  5. 每次校验成功的运行都会重存缓存(pplx_export/commands/common.py:150),日常运行 自行保持新鲜。

设置细节:快速上手 · 配置

导出用了错误的账户(多账户)

问题:归档线程是用错误账户的会话抓取的——例如 --account alice 的运行实际以 bob 拉数据,或归档里出现不属于目标账户的线程。

原因:同一浏览器登录多个账户时,活跃的会话令牌 (__Secure-next-auth.session-token)可能属于另一个账户。若目标账户的 email 未在用户级配置中登记,工具无法识别,只能记一条 warning。

工具的预防机制pplx_export/commands/common.py:93):启动时 transport 调 GET /api/auth/session,把实时 email 与登记值比对。不匹配时自动枚举浏览器里各账户 的会话 cookie(__Secure-pplx.session.<user_id>),逐个替换活跃令牌并探测 session, 直到命中目标 email(pplx_export/commands/common.py:190pplx_export/core/cookies.py:97)。无令牌匹配时命令带清晰报错中止——绝不以错误 账户静默继续。

修复

  • [accounts.<name>] 下登记每个账户的 email(见配置), 并显式传 --account
  • 看启动日志行 [auth] cookie 来源 …,当前账户: …——它在抓取任何数据前报出实时 会话 email。
  • 审计既有归档:每个线程的 thread.jsonexport_via 字段,记录执行导出的账户 (pplx_export/sites/perplexity/fs_writer.py:229)。pplx-export sync-deleted 也用该字段选择在线验证的账户。

机制深究:API 认证 · 发问与账户

「找不到配置文件」——降级模式

问题:启动 warning 提示未找到用户级配置文件、命令以降级模式运行;或显式 --account alice 报错并指向 config.example.toml

原因:三个查找位置都没有配置文件——--config PATH、环境变量 PPLX_EXPORT_CONFIG、默认 ~/.config/pplx-export/config.tomlpplx_export/config.py:113)。两种相关但不同的情形:显式指定的配置路径不 存在会抛 ConfigError;配置损坏(无法解析)一律抛 ConfigError——坏配置绝不 静默降级。

降级模式的影响

  • 账户注册表为空,cookie 归属校验跳过并 warning,命令以占位账户 default 运行 (pplx_export/commands/common.py:51)。显式 --account 则直接报错。
  • pplx-ask ask 跳过自动移入 BOT 空间(结果 JSON 中 moved_to_bot 保持 false), 遥测携带空 user id;发问与归档本身照常工作。
  • 归档落在按用户名回退的账户目录下。

修复:把 config.example.toml 复制为 ~/.config/pplx-export/config.toml,填好 [accounts.<name>]display_name / email / user_id)、[bot_space]default_account —— 见配置

ENTRY_EXPIRED 与 ENTRY_DELETED 的区别

问题:导出或增量同步某线程时报告 ENTRY_EXPIREDENTRY_DELETED,且该线程 再也无法抓取。

原因:两者都以 GET /rest/thread/<uuid> 的 HTTP 400 返回、错误码不同,且同为 终态——线程在平台上已不存在:

错误码 含义 工具映射 终态
ENTRY_EXPIRED 平台清除了该线程(约 3 个月保留期) EntryExpiredErrorpplx_export/core/errors.py:24 expired
ENTRY_DELETED 线程被用户 / 远端主动删除(DELETE /rest/thread/delete_thread_by_entry_uuid 的下游表现) EntryDeletedErrorEntryExpiredError 的子类(pplx_export/core/errors.py:30 deleted

对归档意味着什么

  • 两种状态都永不重试——增量同步不会,加 --force 也不会。终态标记存在 <out>/index/batch_state.json
  • 工具绝不删除或移动本地归档——仓库副本即备份。导出命令登记终态后优雅退出 (pplx_export/commands/export_cmd.py:51)。
  • 子类关系是刻意设计:只认识 EntryExpiredError 的既有路径仍会把 ENTRY_DELETED 当终态处理;感知子类的路径(batch / export / sync-deleted / search-mode-backfill) 则精确归类为 deleted
  • 实践要点:及时导出。过了约 3 个月的清除期,产物 / 报告源链接也不可恢复地过期。

相关:增量同步 · 响应与错误

无法下载的资产(toolu_ 句柄)

问题assets/assets_manifest.json 中部分条目的版本被标记 "no_download_channel": true,且 assets/files/ 下没有对应文件。

原因toolu_ 前缀的 cloud-workspace 句柄(无 URL 形态的 DOC_FILE / CODE_FILE / UNKNOWN)没有 API 下载通道:GET /rest/assets/<asset_uuid>/data 对它们返回 404 ASSET_NOT_FOUNDfile-repository/download 拒绝 file:repo/... 句柄(400)。 这是已知的归档完整性边界,不是导出缺陷。pplx-export assets-backfill 会把这些 版本标记为 no_download_channel 并跳过 (pplx_export/commands/assets_backfill_cmd.py:356)。

修复

  • 目前无可下载——该标记即对此边界的有意记录。
  • 内容往往有内联留存:子代理的页面抽取文本与步骤负载保存在线程的 raw JSON (raw_entries.json / raw_blocks.json)和渲染出的 turns/ 里——先查那里。
  • file-repository/list-files 已被跟踪为潜在的未来救援路径,见 API 发现路线图

manifest 布局:归档布局

日志在哪里?

控制台:默认 INFO 级进度;-v / --verbose 切到 DEBUG(请求追踪、内部判定); warning 与 error 始终显示。

文件:传 --log-file 落盘全量 DEBUG 流(pplx_export/core/logging.py:45):

  • --log-file 不带值时落 <out>/index/logs/<cmd>-<timestamp>.logpplx_export/commands/common.py:218)—— 例如 pplx-ask-ask-20260723-120000.log
  • --log-file PATH 写到指定路径。

其他有助于诊断的状态文件(均在 <out>/index/ 下):

文件 内容
.cookies.json cookie 缓存(12 小时新鲜期;0o600 原子写入——属登录等价凭证,注意保密)
batch_state.json 逐线程导出状态,含 expired / deleted 终态标记
answer_variants_log.jsonl 答案重写变体登记处
library_*.json 各账户的 library 索引快照

参见