Skip to content

Plannotator 故障排查

學完你能做什麼

遇到問題時,你將能夠:

  • 快速定位問題來源(連接埠佔用、Hook event 解析、Git 設定等)
  • 透過日誌輸出診斷錯誤
  • 針對不同錯誤類型採取正確的解決方法
  • 在遠端/Devcontainer 模式下除錯連線問題

你現在的困境

Plannotator 突然無法運作了,瀏覽器沒有開啟,或者 Hook 輸出了錯誤訊息。你不知道如何檢視日誌,也不確定是哪個環節出了問題。你可能嘗試過重新啟動,但問題依然存在。

什麼時候用這一招

以下情況需要故障排查:

  • 瀏覽器沒有自動開啟
  • Hook 輸出錯誤訊息
  • 連接埠佔用導致無法啟動
  • 計畫或程式碼審查頁面顯示異常
  • Obsidian/Bear 整合失敗
  • Git diff 顯示為空

核心思路

Plannotator 的問題通常分為三類:

  1. 環境問題:連接埠佔用、環境變數設定錯誤、瀏覽器路徑問題
  2. 資料問題:Hook event 解析失敗、計畫內容為空、Git 儲存庫狀態異常
  3. 整合問題:Obsidian/Bear 儲存失敗、遠端模式連線問題

除錯的核心是檢視日誌輸出。Plannotator 使用 console.error 輸出錯誤到 stderr,用 console.log 輸出正常資訊到 stdout。區分這兩者能幫你快速定位問題類型。


🎒 開始前的準備

  • ✅ 已安裝 Plannotator(Claude Code 或 OpenCode 外掛)
  • ✅ 瞭解基本的命令列操作
  • ✅ 熟悉你的專案目錄和 Git 儲存庫狀態

跟我做

第 1 步:檢查日誌輸出

為什麼

Plannotator 的所有錯誤都會輸出到 stderr。檢視日誌是診斷問題的第一步。

操作方法

在 Claude Code 中

當 Hook 觸發 Plannotator 時,錯誤訊息會顯示在 Claude Code 的終端機輸出中:

bash
# 你可能看到的錯誤範例
Error: Port 54321 in use after 5 retries (set PLANNOTATOR_PORT to use different port)

在 OpenCode 中

OpenCode 會擷取 CLI 的 stderr 並顯示在介面中:

[stderr] Failed to parse hook event from stdin
[stderr] No plan content in hook event

你應該看到

  • 如果沒有錯誤,stderr 應該為空或僅有預期的提示訊息
  • 如果有錯誤,會包含錯誤類型(如 EADDRINUSE)、錯誤訊息和堆疊資訊(如果有)

第 2 步:處理連接埠佔用問題

為什麼

Plannotator 預設在隨機連接埠啟動伺服器。如果固定連接埠被佔用,伺服器會嘗試重試 5 次(每次延遲 500ms),失敗後報錯。

錯誤訊息

Error: Port 54321 in use after 5 retries (set PLANNOTATOR_PORT to use different port)

解決方案

方案 A:讓 Plannotator 自動選擇連接埠(推薦)

不要設定 PLANNOTATOR_PORT 環境變數,Plannotator 會自動選擇可用連接埠。

方案 B:使用固定連接埠並解決佔用

如果必須使用固定連接埠(如遠端模式),需要解決連接埠佔用:

bash
# macOS/Linux
lsof -ti:54321 | xargs kill -9

# Windows PowerShell
Get-NetTCPConnection -LocalPort 54321 | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }

然後重新設定連接埠:

bash
# macOS/Linux/WSL
export PLANNOTATOR_PORT=54322

# Windows PowerShell
$env:PLANNOTATOR_PORT = "54322"

檢查點 ✅

  • 再次觸發 Plannotator,瀏覽器應該能正常開啟
  • 如果仍然報錯,嘗試換一個連接埠號

第 3 步:除錯 Hook event 解析失敗

為什麼

Hook event 是從 stdin 讀取的 JSON 資料。如果解析失敗,Plannotator 無法繼續。

錯誤訊息

Failed to parse hook event from stdin
No plan content in hook event

可能原因

  1. Hook event 不是有效的 JSON
  2. Hook event 缺少 tool_input.plan 欄位
  3. Hook 版本不相容

除錯方法

檢視 Hook event 內容

在 Hook server 啟動前,印出 stdin 內容:

bash
# 暫時修改 hook/server/index.ts
# 在第 91 行後新增:
console.error("[DEBUG] Hook event:", eventJson);

你應該看到

json
{
  "tool_input": {
    "plan": "# Implementation Plan\n\n## Task 1\n..."
  },
  "permission_mode": "default"
}

解決方案

  • 如果 tool_input.plan 為空或缺失,檢查 AI Agent 是否正確產生了計畫
  • 如果 JSON 格式錯誤,檢查 Hook 設定是否正確
  • 如果 Hook 版本不相容,更新 Plannotator 到最新版本

第 4 步:解決瀏覽器未開啟問題

為什麼

Plannotator 使用 openBrowser 函式自動開啟瀏覽器。如果失敗,可能是跨平台相容性問題或瀏覽器路徑錯誤。

可能原因

  1. 系統預設瀏覽器未設定
  2. 自訂瀏覽器路徑無效
  3. WSL 環境下的特殊處理問題
  4. 遠端模式下不會自動開啟瀏覽器(這是正常的)

除錯方法

檢查是否在遠端模式

bash
# 檢視環境變數
echo $PLANNOTATOR_REMOTE

# Windows PowerShell
echo $env:PLANNOTATOR_REMOTE

如果輸出為 1true,說明是遠端模式,瀏覽器不會自動開啟,這是預期行為。

手動測試瀏覽器開啟

bash
# macOS
open "http://localhost:54321"

# Linux
xdg-open "http://localhost:54321"

# Windows
start http://localhost:54321

你應該看到

  • 如果手動開啟成功,說明 Plannotator 伺服器正常運作,問題出在自動開啟邏輯
  • 如果手動開啟失敗,檢查 URL 是否正確(連接埠可能不同)

解決方案

方案 A:設定自訂瀏覽器(macOS)

bash
export PLANNOTATOR_BROWSER="Google Chrome"

# 或使用完整路徑
export PLANNOTATOR_BROWSER="/Applications/Google Chrome.app"

方案 B:設定自訂瀏覽器(Linux)

bash
export PLANNOTATOR_BROWSER="/usr/bin/firefox"

方案 C:遠端模式手動開啟(Devcontainer/SSH)

bash
# Plannotator 會輸出 URL 和連接埠資訊
# 複製 URL,在本機瀏覽器中開啟
# 或使用連接埠轉發:
ssh -L 19432:localhost:19432 user@remote

第 5 步:檢查 Git 儲存庫狀態(程式碼審查)

為什麼

程式碼審查功能依賴 Git 指令。如果 Git 儲存庫狀態異常(如沒有提交、Detached HEAD),會導致 diff 顯示為空或錯誤。

錯誤訊息

Git diff error for uncommitted: Error: Command failed: git diff HEAD

除錯方法

檢查 Git 儲存庫

bash
# 檢查是否在 Git 儲存庫中
git status

# 檢查目前分支
git branch

# 檢查是否有提交
git log --oneline -1

你應該看到

  • 如果輸出 fatal: not a git repository,說明目前目錄不是 Git 儲存庫
  • 如果輸出 HEAD detached at <commit>,說明處於 Detached HEAD 狀態
  • 如果輸出 fatal: your current branch 'main' has no commits yet,說明還沒有任何提交

解決方案

問題 A:不在 Git 儲存庫中

bash
# 初始化 Git 儲存庫
git init
git add .
git commit -m "Initial commit"

問題 B:Detached HEAD 狀態

bash
# 切換到一個分支
git checkout main
# 或建立新分支
git checkout -b feature-branch

問題 C:沒有提交

bash
# 至少需要一個提交才能檢視 diff
git add .
git commit -m "Initial commit"

問題 D:空 diff(沒有變更)

bash
# 建立一些變更
echo "test" >> test.txt
git add test.txt

# 再次執行 /plannotator-review

檢查點 ✅

  • 再次執行 /plannotator-review,diff 應該正常顯示
  • 如果仍然為空,檢查是否有未暫存或未提交的變更

第 6 步:除錯 Obsidian/Bear 整合失敗

為什麼

Obsidian/Bear 整合失敗不會阻止計畫批准,但會導致儲存失敗。錯誤會輸出到 stderr。

錯誤訊息

[Obsidian] Save failed: Vault not found
[Bear] Save failed: Failed to open Bear

除錯方法

檢查 Obsidian 設定

macOS

bash
cat ~/Library/Application\ Support/obsidian/obsidian.json

Windows

powershell
cat $env:APPDATA\obsidian\obsidian.json

你應該看到

json
{
  "vaults": {
    "/path/to/vault": {
      "path": "/path/to/vault",
      "ts": 1234567890
    }
  }
}

檢查 Bear 可用性(macOS)

bash
# 測試 Bear URL scheme
open "bear://x-callback-url/create?title=Test&text=Hello"

你應該看到

  • Bear 應用程式開啟並建立新筆記
  • 如果沒有任何反應,說明 Bear 未正確安裝

解決方案

Obsidian 儲存失敗

  • 確保 Obsidian 正在執行
  • 檢查 vault 路徑是否正確
  • 嘗試手動在 Obsidian 中建立筆記,驗證權限

Bear 儲存失敗

  • 確保 Bear 已正確安裝
  • 測試 bear://x-callback-url 是否可用
  • 檢查 Bear 設定中是否啟用了 x-callback-url

第 7 步:檢視詳細錯誤日誌(除錯模式)

為什麼

有時錯誤訊息不夠詳細,需要檢視完整的堆疊追蹤和上下文。

操作方法

啟用 Bun 除錯模式

bash
export DEBUG="*"
plannotator review

# Windows PowerShell
$env:DEBUG = "*"
plannotator review

檢視 Plannotator 伺服器日誌

伺服器內部的錯誤會透過 console.error 輸出。關鍵日誌位置:

  • packages/server/index.ts:260 - 整合錯誤日誌
  • packages/server/git.ts:141 - Git diff 錯誤日誌
  • apps/hook/server/index.ts:100-106 - Hook event 解析錯誤

你應該看到

bash
# 成功儲存到 Obsidian
[Obsidian] Saved plan to: /path/to/vault/Plan - 2026-01-24.md

# 儲存失敗
[Obsidian] Save failed: Cannot write to directory
[Bear] Save failed: Failed to open Bear

# Git diff 錯誤
Git diff error for uncommitted: Error: Command failed: git diff HEAD

檢查點 ✅

  • 錯誤日誌包含足夠的資訊來定位問題
  • 根據錯誤類型採取對應的解決方案

踩坑提醒

❌ 忽略 stderr 輸出

錯誤做法

bash
# 只關注 stdout,忽略 stderr
plannotator review 2>/dev/null

正確做法

bash
# 同時檢視 stdout 和 stderr
plannotator review
# 或分離日誌
plannotator review 2>error.log

❌ 盲目重新啟動伺服器

錯誤做法

  • 遇到問題就重新啟動,不檢視錯誤原因

正確做法

  • 先檢視錯誤日誌,確定問題類型
  • 根據錯誤類型採取對應的解決方案
  • 重新啟動只是最後的手段

❌ 在遠端模式下期待瀏覽器自動開啟

錯誤做法

bash
export PLANNOTATOR_REMOTE=1
plannotator review
# 期待瀏覽器自動開啟(不會發生)

正確做法

bash
export PLANNOTATOR_REMOTE=1
plannotator review
# 記錄輸出的 URL,手動在瀏覽器中開啟
# 或使用連接埠轉發

本課小結

  • Plannotator 使用 console.error 輸出錯誤到 stderr,console.log 輸出正常資訊到 stdout
  • 常見問題包括:連接埠佔用、Hook event 解析失敗、瀏覽器未開啟、Git 儲存庫狀態異常、整合失敗
  • 除錯的核心是:檢視日誌 → 定位問題類型 → 採取對應解決方案
  • 遠端模式下不會自動開啟瀏覽器,需要手動開啟 URL 或設定連接埠轉發

下一課預告

下一課我們學習 常見問題

你會學到:

  • 如何解決安裝和設定問題
  • 常見的使用誤區和注意事項
  • 效能最佳化建議

附錄:原始碼參考

點擊展開檢視原始碼位置

更新時間:2026-01-24

功能檔案路徑行號
連接埠重試機制packages/server/index.ts79-80
EADDRINUSE 錯誤處理packages/server/index.ts320-334
Hook event 解析apps/hook/server/index.ts91-107
瀏覽器開啟packages/server/browser.ts45-74
Git diff 錯誤處理packages/server/git.ts139-144
Obsidian 儲存日誌packages/server/index.ts242-246
Bear 儲存日誌packages/server/index.ts252-256

關鍵常數

  • MAX_RETRIES = 5:連接埠重試最大次數
  • RETRY_DELAY_MS = 500:連接埠重試延遲(毫秒)

關鍵函式

  • startPlannotatorServer():啟動計畫審查伺服器
  • startReviewServer():啟動程式碼審查伺服器
  • openBrowser():跨平台瀏覽器開啟
  • runGitDiff():執行 Git diff 指令
  • saveToObsidian():儲存計畫到 Obsidian
  • saveToBear():儲存計畫到 Bear