故障排查指南

当前工作流提示

如果你在调试 agent lifecycle 或 subagent 行为,先看 docs/AGENT_JOBS.org 。Magent 当前通过 spawn_agent 、 send_agent_message 、 wait_agent 、 list_agents 和 close_agent 使用 durable child-agent jobs;旧的一次性 delegate tool 不属于当前 surface。不要把缺少 sandbox parity 诊断成 Magent bug;Codex sandbox behavior 是有意排除的范围。

常见问题

GitHub Actions 失败

melpazoid 遗漏 production file 或 runtime data

问题: melpazoid job 失败,错误类似:

Opening input file: No such file or directory, /workspace/pkg/prompts/system.org

原因: MELPA-style packaging 只复制 recipe 匹配的文件。Magent 打包后仍然需要全部 production libraries 和 bundled runtime data。

解决: 保持 .github/workflows/melpazoid.yml 的 recipe 形状类似:

(magent :fetcher github :repo "Jamie-Cui/magent"
        :files ("lisp/magent*.el" "prompts" "skills"))

显式 glob 提供全部 production Elisp files;显式目录提供 package 通过相对路径加载的 runtime data。ERT 源码应放在 test/ 下,使其不进入 production package;recipe 应与 source-files.txt 和 prompts/manifest.txt 保持一致。

package-lint 报告 ineffective Package-Requires

问题: melpazoid 报告:

Package-Requires outside the main file have no effect.

解决: Package-Requires 只放在 magent.el ,并在 magent-pkg.el 中保持一致。Secondary modules 只在代码中写普通 (require ...) dependencies,不写 package headers。

package license unknown

问题: melpazoid 对模块文件报告 license unknown 。

解决: 每个 Elisp source 都应有 formal license header 或 SPDX line,例如:

;; SPDX-License-Identifier: GPL-3.0-or-later

Live smoke test 在 GitHub Actions 超时

问题: test.yml 的 Run live smoke tests 失败:

Magent live loop tool turn did not finish

原因: CI runner 可能比本地 daemon 慢,timer、tool callback 和 UI rendering 都在同一个 live Emacs process 中运行。

解决: deterministic live smoke waits 要足够适配 CI,不要硬编码本机时间假设。本地复现:

emacs --daemon=magent-ci
EMACSCLIENT="emacsclient -s magent-ci" make test-live-smoke
emacsclient -s magent-ci --eval '(kill-emacs)'

安装问题

“Cannot find gptel”

问题: Magent 需要 gptel 作为依赖。

解决:

(package-install 'gptel)

Byte-compilation warnings

问题: 编译时出现 undefined functions 等 warnings。

解决: 确认依赖已安装且在 load-path 中:

make compile

如果依赖不在 ~/.emacs.d/elpa/ ,显式传入 Makefile 变量,例如 GPTEL_DIR 、 COMPAT_DIR 或 YAML_DIR 。

Runtime 问题

Live Emacs tests 失败或 hang

问题: make test-live 使用真实 gptel provider 时失败、超时,或报告 async timer error。

Live debugging playbook:

  1. 使用 isolated Emacs server。可能 hang 时不要在主编辑 Emacs 上调试。

    emacs --daemon=magent-live-test
    
  2. 始终把 emacsclient 或 make 指向 isolated server:

    emacsclient -s magent-live-test --eval '(emacs-pid)'
    make EMACSCLIENT="emacsclient -s magent-live-test" test-live-smoke
    
  3. 每次 live run 前强制加载当前 checkout 的 source,并确认没有用到 ELPA Magent:

    emacsclient -s magent-live-test --eval \
      '(progn
         (setq debug-on-error t)
         (load-file "/path/to/magent/test/magent-live-test.el")
         (magent-live-test-reload-source)
         (list :repo-source (magent-live-test--repo-source-summary)))'
    

    :repo-source 中每个路径都必须在当前 checkout 下,而不是 ~/.emacs.d/elpa/magent/ 的旧版本。

  4. Batch 或 live verification 前清理 stale bytecode:

    make clean
    

    如果看到 Source file ... newer than byte-compiled file; using older file ,说明 Emacs 正在测试旧代码。

  5. 真实 provider run 优先使用 async status files,避免 emacsclient 阻塞,并保留紧凑状态快照:

    emacsclient -s magent-live-test --eval \
      '(progn
         (setq debug-on-error t)
         (load-file "/path/to/magent/test/magent-live-test.el")
         (magent-live-test-reload-source)
         (magent-live-test-install-trace "/tmp/magent-live-trace.el")
         (magent-live-test-run-async
          (quote magent-live-test-real-emacs-eval-tool)
          "/tmp/magent-live-tool-final.el"))'
    
    cat /tmp/magent-live-tool-final.el
    tail -n 80 /tmp/magent-live-trace.el
    
  6. 测试运行中和结束后检查 isolated server 中的诊断 buffers:

    • *Messages*
    • *Backtrace*
    • *magent-live-test-log*
    • *gptel-log*

    *gptel-log* 是敏感材料。分享或提交任何片段前,先移除 API keys、bearer tokens、request headers 和 provider-specific secrets。

  7. 如果 isolated Emacs server 无响应,只中断或 kill 该 server,不要 kill 主 Emacs:

    emacsclient -s magent-live-test --eval '(kill-emacs 0)'
    

    如果 client 无法连接,找到 emacs --daemon=magent-live-test PID 并只 kill 该 PID。

诊断:

  1. 复现前开启 backtrace:

    (setq debug-on-error t)
    
  2. 从 emacsclient 或 make test-live 重跑失败测试。
  3. 运行中和结束后检查:
    • *Messages* :timer、process filter、byte-code errors
    • *Backtrace* : debug-on-error 打开的 backtrace
    • *magent-log* 或 test-local *magent-live-test-log*
    • *gptel-log* :provider/request failures,分享前必须 redacted
  4. 单个 real tool test 可这样运行:

    (progn
      (load-file "/path/to/magent/test/magent-live-test.el")
      (setq debug-on-error t)
      (magent-live-test-run 'magent-live-test-real-emacs-eval-tool))
    

解决:

  • 先修 *Backtrace* 或 *Messages* 中第一个具体错误,再重跑单个 failing live test,最后跑完整 live suite。
  • 对 *gptel-log* 只分享 summary 或 redacted snippets。

既往 failure signatures:

  • 如果第一个 tool result 后 continuation hang,检查 /tmp/magent-live-trace.el 。出现 gptel-curl-get-args :event enter 但没有对应 :event leave ,通常意味着 gptel 在 curl 启动前遇到 serialization error。检查 tool-call names、tool args 和 assistant tool_calls history 中是否有 Lisp symbols 或非 JSON-safe values。
  • 如果第一个 provider request 发出 tool call,但第二个 request 没有开始,确认 Magent 是否把 tool result 记录进 session,并通过 magent-agent-loop-request-for-current-session 重建 continuation prompt。
  • 如果 continuation 完成但没有 assistant text,检查 turn result 是否包含 ~(:reason empty-completion)~。Magent 不会发起 recovery request;reasoning-only 内容仍与 assistant text 分开。
  • 如果第二个 request 完成但 agent-shell 漏掉 final assistant text,记住 tool-enabled requests 可能是 non-streaming。Non-streaming string callback 可能就是 final completion,而不是 text delta;确认 ACP observer 是否发出了对应的 agent-shell update。
  • 如果 direct emacsclient 通过但 make test-live-smoke 失败,确认设置了 EMACSCLIENT="emacsclient -s magent-live-test" 。
  • 如果测试意外加载旧 Magent,检查 load-history 、 load-path order 和 .elc 文件。 test/magent-live-test.el 使用 source loading with nosuffix ;添加文件到 live reload list 时保持这个行为。

修复 live gptel/tool bugs 后的 known-good verification sequence:

make clean
make test-unit
make compile
make clean
make EMACSCLIENT="emacsclient -s magent-live-test" test-live-smoke

然后在 isolated daemon 中运行两个真实 async diagnostics:

(magent-live-test-run-async 'magent-live-test-real-simple-prompt
                            "/tmp/magent-live-simple-final.el")
(magent-live-test-run-async 'magent-live-test-real-emacs-eval-tool
                            "/tmp/magent-live-tool-final.el")

预期 final status files 包含 :status passed , :repo-source 路径都在当前 checkout 下。Tool test 应包含类似 (:name "emacs_eval" :result "42") 的 tool state,以及 final assistant text MAGENT_TOOL_OK=42 。

“No response from LLM”

问题: Request hang 或 timeout。

诊断:

  1. 使用 C-x b 直接打开 *magent-log* ,检查最新记录。
  2. 检查 gptel 配置:

    gptel-model
    gptel-api-key
    
  3. 直接测试 gptel: M-x gptel 。

解决:

  • 增加 timeout: (setq magent-request-timeout 300) 。
  • 检查网络或代理。
  • 确认 API key 有效。

“Tool execution failed”

问题: Tool calls 返回错误。

诊断:

  1. 检查 *magent-log* 的错误细节。
  2. 确认 tool 已启用: magent-enable-tools 。
  3. 运行 M-x magent-list-agents ,并确认当前 agent-shell session mode。

解决:

  • bash:确认已安装 Bash,且 magent-bash-program 能在 project host 上解析。 TRAMP project 不会回退到本地执行。命令不启用 errexit,但启用 pipefail;需要 fail-fast 串联时使用 && 或显式 set -e 。 rg ... | head 一类限流 pipeline 可能因 SIGPIPE 失败, 应优先使用工具原生 limit 参数。
  • ~emacs_read~:确认固定 operation、target 有效,且 origin buffer 仍存在。
  • ~emacs_eval~:检查语法和 child-process diagnostics。它每次启动新的 ~emacs -Q –batch~,看不到 live buffer 或用户已加载的 package。
  • ~emacs_eval_live~:timeout 只属于 best effort;阻塞的 C primitive 或进程级 failure 仍可能卡死、崩溃 live Emacs。
  • grep:project host 上优先使用 ripgrep(~which rg~),找不到时回退到 ~git grep –no-index –exclude-standard~(~which git~);两者都不存在时明确失败。

TRAMP project 启动或 tool call 卡住

问题: 从 remote file/Dired buffer 启动 Magent,或调用 project tool 时阻塞 Emacs。

诊断:

  1. 先确认同一目录可用普通 TRAMP file operation 访问。
  2. 检查 *magent-log* 与 *Messages* 中的精确 operation。
  3. 确认只有 bash 或 grep 本应启动 project-host process。

解决:

  • ACP placeholder、Action、Doctor 与 emacs_eval 必须保持本地;这些路径出现 remote process 属于 bug。
  • 在 remote project host 上为对应 project-process tool 安装 bash~,并安装 ~rg 或 Git 之一。
  • Remote file tool 仍使用同步 Emacs/TRAMP file API;损坏的 SSH transport 因此 仍可能阻塞一次显式 file operation。修复或中止 TRAMP connection 后再重试。

模型返回的 Elisp 卡死或崩溃 Emacs

问题: 任意 form 不结束、触发 fatal error 或调用 ~kill-emacs~。

诊断:

  1. 运行 ~/authority~,确认实际选择了哪条 eval boundary。
  2. 查询 live buffer、mode、symbol、binding、hook 和 project state 时优先使用 ~emacs_read~。
  3. 确认普通任意代码使用 ~emacs_eval~,其 result metadata 为 ~execution=child-process~。

解决:

  • 任意 evaluation 默认留在 ~emacs_eval~。Parent 持有 timeout,并在 timeout 或 cancellation 时删除一次性 child。
  • 只有任务确实需要修改 live package/buffer state 时才使用 emacs_eval_live~。 每次调用都必须重新批准;~magent-bypass-permission 和已保存的 session allow 都不能跳过。
  • 这个边界隔离 Emacs process failure,不隔离 host authority;代码仍以当前用户 身份访问文件、进程和网络。

Child-agent 行为不符合预期

问题: child-agent task 不能像 durable job 一样 message、wait、list 或 close。

诊断:

  1. 检查代码路径是否使用 spawn_agent 、 send_agent_message 、 wait_agent 、 list_agents 和 close_agent 。
  2. 复读 docs/AGENT_JOBS.org 中的 job lifecycle contract。
  3. 在 agent-shell buffer 中查看紧凑 child-agent updates,并确认 parent session 中持久化的 agent-jobs 数据。
  4. 检查 *magent-log* 中的 nested request 或 tool-call errors。
  5. Resume 后确认 parent session 仍有预期 agent-jobs metadata。

解决:

  • 围绕 job status、transcript/result storage、parent/child session links 和 resume restoration 添加或更新测试。
  • 不要为了该 workflow fix 添加 sandbox-specific checks。

“Permission denied” errors

问题: Tool execution 被 permissions 阻止。

诊断:

运行 M-x magent-list-agents 检查 agent profiles,并确认当前 agent-shell session mode。

解决:

  • 临时 bypass: M-x magent-toggle-bypass-permission 。
  • 或 customize: (setq magent-bypass-permission t) 。
  • 或在 agent-shell buffer 中运行 M-x agent-shell-set-session-mode ,选择权限合适的 agent。

Bypass 不会跳过 emacs_eval 或 emacs_eval_live 的 once-only approval;agent 规则中的 deny 也仍会让 tool 不可用。

Session not saving

问题: Emacs 重启后 session state 丢失。

诊断:

检查 session directory 是否存在且可写:

magent-session-directory  ; Default: ~/.emacs.d/magent/sessions/

解决:

(make-directory magent-session-directory t)

Agent-shell 问题

Agent-shell buffer 不更新

问题: Streaming 看起来卡住。

诊断:

  1. 检查 agent-shell buffer 中的 request status。
  2. 检查 *Messages* 。
  3. 在 agent-shell buffer 中按 C-c C-c 并确认 interrupt。

解决:

  • 使用 M-x magent-start 启动另一个 shell,然后选择新 session。
  • 如果仍然存在,重启 Emacs。

性能问题

Streaming 太慢

问题: Response 像逐字显示。

解决:

  • 确认 agent-shell 版本满足 README 要求。
  • 在新的 M-x magent-start buffer 中复现,并检查 *Messages* 和 *magent-log* 是否有 update/rendering error。

内存占用高

问题: Emacs memory 随时间增长。

解决:

(setq magent-max-history 50)

当前 session 不再需要保留在 active buffer 时,使用 M-x magent-start 启动另一个 shell,然后选择新 conversation。

Diagnostic Commands

Self-Check

M-x magent-action-run-doctor

运行 Magent-specific diagnosis request 并报告问题。

View Logs

C-x b *magent-log* RET

显示 request/response log。

Check Configuration

M-x describe-variable RET magent-enable-tools
M-x describe-variable RET gptel-model
M-x describe-variable RET gptel-api-key

获取帮助

如果问题仍然存在:

  1. 运行 M-x magent-action-run-doctor 并保存输出。
  2. 检查 *magent-log* 和 *Messages* 。
  3. 开 GitHub issue,并提供 reproduction steps。
  4. 附上 Emacs version: M-x emacs-version 。