microsoft / microsoft/amplifier

Session hangs indefinitely: filesystem tools block forever on unresponsive UNC path; parent delegate never returns

Open
#319 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
3.1k
Forks
261
Avg merge
3h 28m
Merged PRs (30d)
13

Description

Session hangs indefinitely: filesystem tools block forever on unresponsive UNC path; parent delegate never returns

Summary

An interactive session hung silently for ~14.5 hours (until manually killed) because a delegated sub-agent issued filesystem tool calls (grep, read_file) against an RDP-redirected UNC share (\\tsclient\Z\...) that became unresponsive. There is no tool-level timeout, watchdog, or heartbeat anywhere in the chain:

blocked filesystem I/O → sub-session never produces its next LLM request → parent's delegate tool call never receives a result → entire session hangs with no error, no log output, no indication anything is wrong.

A secondary but independently serious finding: even on a healthy share, an unscoped repo-root grep over RDP drive redirection took 55 minutes 9 seconds and returned 0 matches (a near-hang by itself, with a misleading result — see "Contributing factors").

Environment

  • OS: Windows 11 (10.0.26200)
  • Working directory: \\tsclient\Z\home\dan\code\freshell — an RDP drive-redirection UNC share pointing at a Linux client filesystem
  • Repo characteristics: repo root contains node_modules, .git, dist, release, playwright-report, and a .worktrees directory holding 44 worktree copies of the repo
  • WSL: not installed (relevant to a secondary finding below)
  • Provider/model: anthropic / claude-fable-5
  • Bundle: anchors (delegate to anchors:explorer)

Timeline (UTC; local = UTC-7)

Time Event
2026-07-08 23:40:23 session:start — prompt asks to read up on a tauri port and propose a plan
23:40:39 Turn-1 tools (read_file repo root, todo) complete in ~1.4 s — share healthy
23:40:58 LLM iter-2 response → delegate to anchors:explorer
23:40:59.664 delegate:agent_spawnedlast parent event before the hang
23:41:09 Sub-agent LLM responds → 3 parallel tool calls
23:41:10.181 Sub-session tool:pre × 3: repo-root grep -i tauri, read_file repo root, read_file .worktrees
Log ends. No tool:post, no error, no timeout. Nothing for ~14 h 35 m.
2026-07-09 14:16:31 session:resume — session manually killed and restarted by user
14:17:16 Resumed explorer sub-session re-runs the identical repo-root grep
15:12:26 tool:post for that grep: 3,309 s (55 m 09 s), 0 matches

Evidence (verbatim event-log excerpts; large payloads trimmed as [...], no secrets present)

1. Parent session — last events before the hang
# parent events.jsonl, line 21 (LLM iter-2 response; raw content trimmed)
{"ts": "2026-07-08T23:40:58.664193200+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "llm:response", "duration_ms": 17880, "redaction": {"applied": true, "rules": ["secrets", "pii-basic"]}, "session_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "status": "ok", "data": {"model": "claude-fable-5", "parent_id": null, "provider": "anthropic", "rate_limits": {"input_tokens_limit": 4000000, "input_tokens_remaining": 3992000, [...]}, "raw": {"container": null, "content": [{"signature": "[...]", "thinking": "", "type": "thinking"}, [...]}}}

# parent events.jsonl, line 29 (LAST parent event before 14.5h gap)
{"ts": "2026-07-08T23:40:59.664168100+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "delegate:agent_spawned", "session_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "data": {"agent": "anchors:explorer", "context_depth": "none", "context_scope": "conversation", "model_role": null, "parallel_group_id": "3406152b-bbdb-4789-a042-4ee5a182fca6", "parent_id": null, "parent_session_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "provider_preferences": null, "sub_session_id": "0000000000000000-d7e764a0c0b74e86_anchors-explorer", "tool_call_id": "toolu_01XNLUqpMX6xtzzVymC7Eeg8"}}
2. Hung explorer sub-session — three tool:pre events, then the log simply ends

These are the final lines of the file; no tool:post ever follows for any of the three:

# d7e764a0c0b74e86_anchors-explorer events.jsonl, lines 17-19 (end of file)
{"ts": "2026-07-08T23:41:10.181105500+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "tool:pre", "session_id": "0000000000000000-d7e764a0c0b74e86_anchors-explorer", "data": {"parallel_group_id": "dfb5232d-96a5-4a3f-9ee4-68c81f5ccad2", "parent_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "tool_call_id": "toolu_015uAasGVYJzUn7TW2vM6Mka", "tool_input": {"-i": true, "output_mode": "files_with_matches", "path": "\\\\tsclient\\Z\\home\\dan\\code\\freshell", "pattern": "tauri"}, "tool_name": "grep"}}
{"ts": "2026-07-08T23:41:10.181162700+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "tool:pre", "session_id": "0000000000000000-d7e764a0c0b74e86_anchors-explorer", "data": {"parallel_group_id": "dfb5232d-96a5-4a3f-9ee4-68c81f5ccad2", "parent_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "tool_call_id": "toolu_01M93zX6KfpJPusEyoezgPqe", "tool_input": {"file_path": "\\\\tsclient\\Z\\home\\dan\\code\\freshell\\.worktrees"}, "tool_name": "read_file"}}
{"ts": "2026-07-08T23:41:10.181128500+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "tool:pre", "session_id": "0000000000000000-d7e764a0c0b74e86_anchors-explorer", "data": {"parallel_group_id": "dfb5232d-96a5-4a3f-9ee4-68c81f5ccad2", "parent_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "tool_call_id": "toolu_019qjZFX4dmoJadxHRY6HNsT", "tool_input": {"file_path": "\\\\tsclient\\Z\\home\\dan\\code\\freshell"}, "tool_name": "read_file"}}

Note that two of the three blocked calls are trivial directory listings that completed in 0.9–1.8 s in the resumed session — this is not "slow tool", it is I/O blocked indefinitely on a dead redirected share.

3. session:resume next day (~14 h 35 m gap after line 29)
# parent events.jsonl, line 30
{"ts": "2026-07-09T14:16:31.850838200+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "session:resume", "session_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "data": {"parent_id": null}}
4. Post-resume: the identical grep on a healthy share — 55 m 09 s, 0 matches
# 21a73eff3f104c60_anchors-explorer events.jsonl, line 17 (tool:pre)
{"ts": "2026-07-09T14:17:16.790788300+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "tool:pre", "session_id": "0000000000000000-21a73eff3f104c60_anchors-explorer", "data": {"parallel_group_id": "75e00007-45b6-4a57-8d7a-d8da39a445ea", "parent_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "tool_call_id": "toolu_01RN1vexS9GH4xbHgyHASnVu", "tool_input": {"-i": true, "output_mode": "files_with_matches", "path": "\\\\tsclient\\Z\\home\\dan\\code\\freshell", "pattern": "tauri"}, "tool_name": "grep"}}

# 21a73eff3f104c60_anchors-explorer events.jsonl, line 20 (matching tool:post, +55m09s, 0 matches)
{"ts": "2026-07-09T15:12:26.212156200+00:00", "lvl": "INFO", "schema": {"name": "amplifier.log", "ver": "1.0.0"}, "event": "tool:post", "session_id": "0000000000000000-21a73eff3f104c60_anchors-explorer", "data": {"parallel_group_id": "75e00007-45b6-4a57-8d7a-d8da39a445ea", "parent_id": "6094c395-790b-4d8f-b97d-70901b099e3e", "result": {"error": null, "output": {"files": [], "matches_count": 0, "output_mode": "files_with_matches", "pattern": "tauri", "total_matches": 0}, "success": true}, "tool_call_id": "toolu_01RN1vexS9GH4xbHgyHASnVu", "tool_input": {"-i": true, "output_mode": "files_with_matches", "path": "\\\\tsclient\\Z\\home\\dan\\code\\freshell", "pattern": "tauri"}, "tool_name": "grep"}}
5. Transcript repair on resume (artifact, not cause — included for completeness)
# parent transcript.jsonl.backup, lines 3-5
{"role": "tool", "tool_call_id": "toolu_015Y4wB4sE9KX8eD5L3DNDSW", "name": "read_file", "content": "{\"error\": \"unknown_error\", \"message\": \"Tool execution was interrupted and no result was captured.\"}"}
{"role": "tool", "tool_call_id": "toolu_01At8CZrTvTtUdvdHmpukbY8", "name": "todo", "content": "{\"error\": \"unknown_error\", \"message\": \"Tool execution was interrupted and no result was captured.\"}"}
{"role": "assistant", "content": [{"type": "text", "text": "The previous tool calls were interrupted. This response was automatically repaired."}]}

Root cause

Filesystem tool execution (grep, read_file) has no timeout. When the underlying I/O blocks indefinitely — which is standard behavior for RDP drive-redirection (\\tsclient) when the RDP session disconnects or the client sleeps — the tool call never completes and never errors. Because the sub-session is awaited synchronously by the parent's delegate call, the block propagates all the way up and the session hangs silently with zero observability.

Contributing factors

  1. No delegate heartbeat/timeout. The parent had no way to notice its sub-session had produced no events for 14+ hours.
  2. Unscoped grep is pathological on network shares. A repo-root grep over \\tsclient scanned node_modules, .git, dist, and 44 worktree copies file-by-file, taking 55 minutes even when healthy. Ripgrep may also be unavailable/slower in this path (fallback engine), compounding it.
  3. Misleading 0-match result. After 55 minutes, the grep returned 0 matches for "tauri" even though a rust-tauri-port worktree exists under .worktrees/ — hidden dot-directories are skipped by default ignore rules, so the agent burned an hour and got a wrong answer. The default-exclusion behavior interacting with dot-directories deserves a look of its own.
  4. Secondary: bash tool routes to WSL and fails on machines without a distribution. Every bash call fails with Windows Subsystem for Linux has no installed distributions (returncode 1, UTF-16LE stdout). This is a fast failure rather than a hang, but it (a) breaks agents whose instructions assume a working shell (e.g. git branch -a), (b) makes gh-based workflows impossible, and (c) the UTF-16LE output is garbled when interpreted as UTF-8. Consider native PowerShell/cmd fallback or capability detection at startup.

Suggested fixes

  1. Hard timeout on filesystem tool execution (grep, read_file, glob), with a shorter default for UNC/network paths. A blocked read should fail loudly in seconds-to-minutes, not never.
  2. Delegate watchdog: parent-side timeout and/or sub-session heartbeat (e.g. "no event emitted in N minutes → fail the delegate call with diagnostics").
  3. Grep guardrails: warn or require confirmation for repo-root scans on network paths; surface elapsed time; consider a per-call time budget with partial results.
  4. Ignore-rule transparency: when a search returns 0 matches and default exclusions skipped directories (dot-dirs, node_modules, ...), say so in the result payload.
  5. Bash/WSL capability detection with a clear error (or native-shell fallback) on Windows machines without WSL distributions.

Session references (local to reporter's machine)

  • Parent session: 6094c395-790b-4d8f-b97d-70901b099e3e
    C:\Users\Admin\.amplifier\projects\--tsclient-Z-home-dan-code-freshell\sessions\6094c395-790b-4d8f-b97d-70901b099e3e\events.jsonl
  • Hung explorer sub-session: 0000000000000000-d7e764a0c0b74e86_anchors-explorer
  • Post-resume explorer sub-session: 0000000000000000-21a73eff3f104c60_anchors-explorer

Full event logs available on request (they contain workspace paths but no secrets).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the grep, read_file, glob, and delegate entry points against the event-log excerpts in the issue. Reproduce a blocked UNC call if possible, then verify that filesystem calls and delegated sub-sessions fail within a bounded time with diagnostics; the suggested grep guardrails and WSL capability behavior are additional scope to assess.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, python
Domain
devtools, operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.