| name | debug-task |
| description | Debug agent task execution infrastructure issues — wrong cwd, wrong files, wrong venv, browser startup failures, agent retry loops, skill loading failures |
Debug Task Infra
Debug agent task execution infrastructure issues by analyzing agent logs.
Core Philosophy
Every agent failure, detour, or workaround is an infra/platform bug — not an agent problem.
When an agent:
- Tries a wrong file path then searches for the right one → catalog or path resolution bug
- Uses wrong CLI syntax then self-corrects → skill docs not loaded or incomplete
- Takes a screenshot but can't find/view it → tool integration bug
- Retries a command with different args → missing docs or unclear API
- Reflects "no failures" when there were failures → reflection prompt bug
Even if the agent eventually succeeds, each detour:
- Wastes tokens and time
- Signals a gap in the platform that WILL hit other tasks
- Must be traced to a specific infra root cause and filed as a bug
Do NOT dismiss detours as "the agent will self-correct." Your job is to
find every single failure step, trace it to a code/config/prompt root cause,
and report it.
When to use
When a task execution shows symptoms like:
- Agent sees unexpected files or can't find expected ones
- Agent runs in wrong working directory
- Browser (Ziniao/Chrome) fails to start or takes multiple retries
- Task uses wrong Python environment
- Store context (bookmarks, browser config) missing from agent prompt
- Agent repeats same bash command 3+ times (infra issue, not agent fault)
- Agent repeats browser-open attempts (browser startup failure)
- Agent can't load skills (wrong skill path or skill not synced)
- Agent passes wrong arguments to tools (schema mismatch)
- Agent uses workarounds for things that should "just work"
- Agent's post-task reflection misses failures that clearly happened
Environment first: are you in WSL debugging a native-Windows server?
Before running ANY command below, figure out where the server actually
runs. vibe-seller ships as a native-Windows install and as a
Linux/WSL install, and the two do not share a data directory. Debugging
the wrong one is the single biggest time-sink — you'll read a stale DB,
grep empty logs, and "fix" a store that isn't the one serving traffic.
Detect the topology:
curl -s -m3 http://127.0.0.1:7777/api/auth/me
ps aux | grep -Ei 'uvicorn|app\.main' | grep -v grep
powershell.exe -NoProfile -Command "Get-Process python,pythonw -ErrorAction SilentlyContinue | Select Id,Path"
When the live server is native-Windows, everything relocates. The
real runtime data root is /mnt/c/Users/<WinUser>/.vibe-seller/
(commonly <WinUser>=Administrator), NOT ~/.vibe-seller. Re-point
every path in this doc:
| This doc says | On a WSL→Windows box, use |
|---|
~/.vibe-seller/data/vibe_seller.db | /mnt/c/Users/<WinUser>/.vibe-seller/data/vibe_seller.db |
logs/backend_7777.log | /mnt/c/Users/<WinUser>/.vibe-seller/logs/ |
~/.vibe-seller/tasks/{id}/ | /mnt/c/Users/<WinUser>/.vibe-seller/tasks/{id}/ |
~/.vibe-seller/bin/<slug>/browser-use | /mnt/c/Users/<WinUser>/.vibe-seller/bin/<slug>/browser-use |
~/.vibe-seller/.claude/skills/ | /mnt/c/Users/<WinUser>/.vibe-seller/.claude/skills/ |
app code (app/skills/…) | …/Programs/VibeSeller/.venv/Lib/site-packages/app/… |
sqlite3 reads the Windows DB fine over /mnt/c. There is often ALSO a
stale ~/.vibe-seller sandbox in WSL from earlier dev — it has a
different stores table (decoy store names, wrong ids). If a store
you expect is missing, or the ids don't match the live /api/stores
response, you're reading the wrong DB.
Driving a store's browser-use wrapper from WSL
The per-store wrapper is generated by the Windows install with CRLF
line endings, and it execs a Windows browser-use.EXE. Two failures
bite immediately:
-
CRLF breaks WSL bash — execing it directly gives
/usr/bin/env: 'bash\r': No such file or directory; running it via
WSL bash gives set: pipefail: invalid option name. Do NOT
dos2unix the file (it's regenerated on every server boot, and a
sanitized copy then can't find the Windows .EXE). Instead run it
through the install's bundled Git-for-Windows bash, which tolerates
CRLF and resolves the Windows exec path:
BASHEXE='/mnt/c/Users/<WinUser>/AppData/Local/Programs/VibeSeller/git/bin/bash.exe'
WU_WIN='C:\Users\<WinUser>\.vibe-seller\bin\<slug>\browser-use'
TASK_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
run(){ "$BASHEXE" -c "export VIBE_TASK_ID='$TASK_ID'; export PYTHONIOENCODING=utf-8 PYTHONUTF8=1; '$WU_WIN' $1"; }
run "open https://sellercentral.amazon.<tld>/home"
run "state"
-
GBK console → UnicodeEncodeError — the Windows Python console
codec is GBK, so any page with Arabic/CJK text crashes state/eval
with 'gbk' codec can't encode character. Always export
PYTHONIOENCODING=utf-8 and PYTHONUTF8=1 (shown above) before the
wrapper call.
Downloads triggered through the CDP-proxied browser land in
/mnt/c/Users/<WinUser>/.vibe-seller/downloads/<slug>/ (the proxy
overrides Chrome's download dir per ziniao.py). Screenshots: pass a
native Windows path (C:\...\downloads\<slug>\shot.png) to
screenshot, then Read it from the /mnt/c equivalent.
For the browser-driving specifics (session rotation, wedged-daemon
recovery, aux sessions) see the debug-store skill — the same
WSL→Windows path/CRLF/UTF-8 rules apply there.
Restarting the native-Windows server
./restart.sh is WSL-only. To restart the Windows server, stop its
pythonw/tray process and relaunch the installed app (see
docs/windows-setup.md). Skills deploy by syncing repo app/skills/
into …/Programs/VibeSeller/.venv/Lib/site-packages/app/skills/; the
server's skills_sync.fetch() copies them to
…/.vibe-seller/.claude/skills/ at boot.
Debug methodology
RULE: Read agent logs BEFORE any conclusion
Every time this skill is invoked, you MUST read the actual agent debug
logs before making any claim about what happened. Do not assume from
file existence, code reading, or task_messages alone. The agent debug
logs are the source of truth.
grep "Starting agent.*{task_id}" logs/backend_7777.log
grep "AGENT_DEBUG.*{task_id}" logs/backend_7777.log | grep "{date}"
ls ~/.claude/projects/*{task_id}*/*.jsonl
grep -c "unique string from SKILL.md" <transcript.jsonl>
Common mistakes to avoid:
- Reading logs from the wrong run (task restarted with different profile)
- Checking transcript before the task finishes — skill loading may happen
mid-task, not at start. Wait for task to complete before concluding.
- Assuming a skill is "loaded" because the file exists in the workspace
- Assuming
slash_commands listing = skill content in LLM context (it doesn't —
only metadata loads on discovery, body loads on trigger)
- Making claims about what the agent "saw" without transcript evidence
- Skipping the transcript file — it's the only way to confirm skill body loading
Step 0: Pick the task to debug
If the user didn't specify a task ID, find the most recent task from the last hour:
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT id, status, substr(result,1,100), substr(error,1,100) \
FROM tasks WHERE created_at > datetime('now', '-1 hour') \
ORDER BY created_at DESC LIMIT 5;"
If exactly one task was active in the last hour, debug that one.
If multiple, ask the user which one. If none, ask the user for a task ID.
Step 1: Pull ALL task messages
Read every message — not just errors. Detours hide in thinking messages
where the agent says things like "let me try another approach" or "file
doesn't exist, let me search."
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT seq, role, content FROM task_messages \
WHERE task_id='{task_id}' ORDER BY seq;"
Step 2: Walk through sequentially and flag EVERY detour
For each step, ask: "Did this step succeed on the first try?"
If not, classify the failure:
| Failure Type | Signal in Logs | Root Cause Category |
|---|
| Wrong file path → search/glob → find correct path | Read error → Glob → Read success | Catalog/path resolution bug |
| Hallucinated CLI command → error → correct syntax | Bash error with usage/invalid choice message | Skill docs not effective enough |
| Tool output not usable → workaround | Screenshot returns bytes, agent searches for .png | Tool integration gap |
| File doesn't exist but agent expected it | Read error "File does not exist" | Catalog lists nonexistent file, or agent guessed |
| Duplicate table headers in catalog | Agent reads garbled catalog | Catalog generation bug |
| Browser open retried (even once) | >1 browser-use open to same URL | CDP proxy / Ziniao / wrapper script bug |
| Agent says "no failures" in reflection | Contradicts actual log | Reflection prompt doesn't force log review |
Step 3: For each detour, trace to root cause
Every detour must map to ONE of these:
- Catalog bug — wrong path, missing
project/ prefix, duplicate headers, unlisted file
- Skill docs bug — missing command, wrong syntax example, undocumented limitation
- Tool integration bug — output not consumable, file not saved where expected
- System prompt bug — unclear instructions, missing "ONLY read catalog files"
- Workspace bug — missing symlinks, wrong isolation, files not synced
- Reflection prompt bug — agent misses failures, doesn't save learnings
Step 4: Report findings
For each bug, provide:
- Seq range: which message steps were wasted
- What happened: agent action → error → workaround
- Steps wasted: count of unnecessary steps
- Root cause: specific code/file/prompt that caused it
- Fix location: exact file and what to change
Known bug patterns (from past investigations)
Catalog path resolution
The L1 catalog (app/knowledge/CATALOG.md) lists files like common/amazon-sites.md.
These are synced to ~/.vibe-seller/knowledge/project/common/amazon-sites.md.
But the store CATALOG.md copies L1 entries verbatim without adding the project/ prefix.
From the agent's CWD, knowledge/ symlinks to ~/.vibe-seller/knowledge/, so the
correct relative path is knowledge/project/common/amazon-sites.md — but the catalog
says common/amazon-sites.md.
Fix: _filter_l1_for_store() in app/workspace/knowledge_sync.py should prepend
project/ to L1 file paths in the store catalog, or the system prompt should tell the
agent the base path.
Duplicate table header in store CATALOG
_filter_l1_for_store() returns a string starting with | File | Relevance | Summary |
header. If _build_store_catalog() also adds a header, or if the function is called
twice, the catalog gets a duplicate header row.
Check: app/workspace/knowledge_sync.py lines around _build_store_catalog and
_filter_l1_for_store.
Agent hallucinates CLI commands (browser-use and others)
Agent invents CLI syntax that doesn't exist instead of using the commands
documented in the loaded skill. Examples seen in the wild:
browser-use scroll 10 (correct: browser-use scroll down --amount 500)
browser-use get text without index (correct: browser-use get text <index>)
browser-use screenshot without path then searching for .png files
How skill loading works (important for diagnosis):
Skills go through 3 stages — discovery ≠ loading ≠ in context:
- File exists —
.claude/skills/ is copied (not symlinked) into the
task workspace from ~/.vibe-seller/.claude/skills/
(app/workspace/manager.py ~line 710, shutil.copytree)
- Discovered — Claude Code finds the SKILL.md via
--add-dir and lists
it in the init event's slash_commands array
- Content in LLM context — the SKILL.md content is actually sent to
the LLM as part of the prompt. This is the step that matters and the
step that's hardest to verify.
CRITICAL: A skill appearing in slash_commands in the init event does
NOT prove its content is in the LLM's context window. Claude Code may
defer loading skill content until the skill is invoked or until a matching
allowed-tools pattern fires.
IMPORTANT: browser-use SKILL.md is an upstream/official doc from the
browser-use project. Do NOT modify it to fix agent behavior issues.
Diagnosis steps (in order of evidence strength):
-
Check the init event for the correct run (watch for task restarts!):
grep "Starting agent.*{task_id}" logs/backend_7777.log
grep "AGENT_DEBUG.*{task_id}.*system.*init" logs/backend_7777.log
Look for slash_commands — does the skill name appear? If NO → file
missing or --add-dir wrong → infra bug.
If YES → skill was discovered but this does NOT mean body was loaded.
-
Check the transcript file (definitive evidence):
Claude Code saves full transcripts at (replace <user> with your
macOS / Linux username and <repo> with the repo dir):
~/.claude/projects/-Users-<user>-Desktop-<repo>-tasks-{task_id}/{session_id}.jsonl
Search for unique strings from the SKILL.md body:
ls ~/.claude/projects/*{task_id}*/*.jsonl
grep -c "browser-use doctor" <transcript.jsonl>
grep -c "Browser Automation with browser-use CLI" <transcript.jsonl>
If count is 0 → skill body was NEVER loaded into context.
If count > 0 → skill body was loaded.
-
Check if agent ever explicitly Read the skill file:
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT content FROM task_messages \
WHERE task_id='{task_id}' AND content LIKE '%browser-use/SKILL.md%';"
Per ctx7 docs, Claude Code skill loading is 3-stage:
- Stage 1: metadata (name + description) loads immediately on discovery
- Stage 2: SKILL.md body loads when triggered by user queries
- Stage 3: references/examples load on demand
If skill metadata is discovered but body never loads, the triggering
mechanism failed. Known causes:
- Duplicate skill discovery (task CWD is inside the git repo at
~/.vibe-seller/, so Claude Code finds .claude/skills/ at the
git root AND in the task workspace copy) — check init event for
duplicate (project) entries
- Skill directory structure issue (wrong path, symlink, missing files)
- Claude Code version-specific bugs in skill loading
Classification:
- Skill file missing from workspace → infra bug (workspace prep / skill sync)
--add-dir not pointing to workspace → infra bug (claude_backend.py)
- Skill discovered but body not in context (transcript confirms) →
skill loading/triggering bug (investigate Claude Code's trigger
mechanism, possibly model-specific or language-specific)
- Skill body confirmed in context but agent ignored → LLM behavior
Ziniao/browser-use open must succeed on first call
The infra handles all browser lifecycle: CDP mux proxy, wrapper scripts,
session management, auto-retry at the infra level. From the agent's
perspective, browser-use open <url> is a one-shot operation that
must always succeed on the first call.
Any retry by the agent = infra bug. This includes:
- Agent calls
browser-use open more than once for the same URL
- Agent calls
browser-use state and gets empty/error, then re-opens
- Agent sleeps and retries after open "just in case"
Root causes (all in infra, not agent):
- CDP mux proxy not routing correctly →
cdp_mux_proxy.py
- Ziniao process not started before agent launch →
browser/manager.py
- Wrapper script not injecting correct
--session/--cdp-url → ~/.vibe-seller/bin/{store}/browser-use
- Port conflict between concurrent tasks → CDP proxy isolation bug
- Stale browser profile → wrapper script or profile management
Check:
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT content FROM task_messages \
WHERE task_id='{task_id}' AND role='tool_use' \
AND content LIKE '%browser-use open%';"
cat ~/.vibe-seller/bin/{store}/browser-use
lsof -i | grep -i cdp
Agent reads files not in catalog
Agent guesses file names like seller-info.md that don't exist, despite having
read the CATALOG.md which lists only existing files. The system prompt says to
"Read the store catalog... Load only the files listed" but isn't forceful enough.
Fix: System prompt should say: "The catalog is the COMPLETE list of available
files. Do NOT attempt to read files not listed in it."
Debug checklist (infrastructure)
1. Database state
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT id, status, result, error FROM tasks ORDER BY created_at DESC LIMIT 5;"
2. Agent logs (backend logs)
Check logs/backend_<port>.log (e.g., logs/backend_7777.log):
tail -f logs/backend_7777.log | grep -Ei "error|fail|warn"
grep "task_id=xxx" logs/backend_7777.log
3. Working directory
ps aux | grep "claude.*{task_id}" | grep -oE "\-\-add-dir [^ ]+"
Expected: ~/.vibe-seller/tasks/{task_id}/
4. Workspace isolation
ls -la ~/.vibe-seller/tasks/{task_id}/
ls -la ~/.vibe-seller/tasks/{task_id}/.claude/skills/
readlink ~/.vibe-seller/tasks/{task_id}/knowledge
5. Browser startup
sqlite3 ~/.vibe-seller/data/vibe_seller.db "SELECT * FROM browser_sessions;"
cat ~/.vibe-seller/bin/{store-slug}/browser-use
6. Store context injection
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT substr(content,1,500) FROM task_messages \
WHERE task_id='{task_id}' AND seq=1;"
Key code paths
| File | Responsibility |
|---|
app/routers/tasks.py | _auto_run_task(), context injection, _build_store_context() |
app/ai/claude_backend.py | Process spawn, cwd, env vars, venv activation |
app/workspace/ | workspace_manager.prepare_task_workspace(), isolation |
app/workspace/knowledge_sync.py | Catalog generation (L1/L2/L3), path resolution |
app/browser/manager.py | Browser config, wrapper scripts, startup logic |
app/skills/ | Built-in skills, skill manifest, skill sync |
app/prompts/reflection.md | Post-task reflection prompt for knowledge capture |
app/prompts/design_system.md | Planning agent instructions, catalog usage |
~/.vibe-seller/ | Runtime: data/, tasks/, .claude/skills/, bin/ |
Common root causes
| Symptom | Likely cause | Fix location |
|---|
| Wrong CWD | prepare_task_workspace() not used or cwd not passed | claude_backend.py |
| Wrong venv | VIRTUAL_ENV not set or wrong PATH | claude_backend.py spawn |
| Wrong files | Workspace not isolated, agent sees parent/other tasks | workspace/ isolation |
| Browser fails | Startup race, port conflict, stale profile | browser/manager.py |
| Missing context | _build_store_context() returns empty/wrong | tasks.py context build |
| Skill not found | Skill not synced to ~/.vibe-seller/.claude/skills/ | app/skills/sync.py |
| Hallucinated CLI syntax | Skill body not loaded — agent didn't invoke /skill | System prompt must tell agent to load skill before use |
| Tool output not usable | Agent can't consume base64/binary output | Skill docs + tool integration |
| Browser open retry (even once) | CDP proxy, Ziniao startup, or wrapper bug | cdp_mux_proxy.py, browser/manager.py, wrapper scripts |
| Catalog path wrong | L1 paths missing project/ prefix in L3 catalog | knowledge_sync.py |
| Duplicate catalog header | _filter_l1_for_store + _build_store_catalog double header | knowledge_sync.py |
| Agent guesses files | System prompt doesn't enforce catalog-only reads | design_system.md |
| Reflection misses failures | Prompt doesn't force sequential log review | reflection.md |
Quick commands
tail -100 logs/backend_7777.log | grep -Ei "error|fail|exception"
find ~/.vibe-seller/tasks -type d -mtime -1 | head -5
ps aux | grep -E "claude|browser-use" | grep -v grep
sqlite3 ~/.vibe-seller/data/vibe_seller.db "SELECT * FROM browser_sessions;"
sqlite3 ~/.vibe-seller/data/vibe_seller.db \
"SELECT task_id, substr(content,1,150) FROM task_messages \
WHERE content LIKE '%error%' OR content LIKE '%fail%' \
ORDER BY created_at DESC LIMIT 10;"
diff -r app/skills/amazon-invoice ~/.vibe-seller/.claude/skills/amazon-invoice \
2>/dev/null || echo "Skills differ or not synced"
cat ~/.vibe-seller/stores/{slug}/CATALOG.md
ls ~/.vibe-seller/knowledge/project/common/