Skip to content

fix: MCP kill_session 400 + extended working stall detection#597

Merged
OneStepAt4time merged 1 commit intomainfrom
fix/560-562-mcp-kill-stall
Mar 30, 2026
Merged

fix: MCP kill_session 400 + extended working stall detection#597
OneStepAt4time merged 1 commit intomainfrom
fix/560-562-mcp-kill-stall

Conversation

@OneStepAt4time
Copy link
Copy Markdown
Owner

Summary

Changes

src/mcp-server.ts

  • AegisClient.request(): Only set Content-Type: application/json when opts.body is defined (DELETE requests have no body)

src/monitor.ts

  • handleWatcherEvent(): Stall timer only resets when event.messages.length > 0; file-only growth updates bytes but preserves timestamp
  • checkForStalls(): New Type 5 extended working stall β€” triggers when session has been continuously working for stallThresholdMs * 3 regardless of byte changes

Test plan

  • New test: killSession does NOT send Content-Type header (mcp-server.test.ts)
  • New tests: Type 5 extended working stall detection (5 tests in stall-detection.test.ts)
  • New tests: handleWatcherEvent stall timer behavior (4 tests in stall-detection.test.ts)
  • All 187 relevant tests pass (stall-detection + mcp-server)
  • TypeScript compilation clean (npx tsc --noEmit)

Generated by Hephaestus (Aegis dev agent)

, #562)

Two fixes:

1. Issue #560: MCP kill_session tool returned Bad Request because AegisClient
   unconditionally set Content-Type: application/json on all requests including
   bodyless DELETE. Fastify's JSON parser rejects empty body with 400.
   Fix: only set Content-Type when opts.body is defined.

2. Issue #562: Sessions stuck in CC's "Misting" internal loop showed as
   "working" indefinitely because two problems:
   a) handleWatcherEvent reset stall timer on any file offset change, even when
      no messages were parsed (e.g., CC wrote JSONL metadata/whitespace).
      Fix: only reset stall timer when real messages arrive.
   b) No stall type caught the case where CC is "working" for very long periods
      while still writing bytes (internal loops).
      Fix: added Type 5 "extended_working" stall that triggers at 3x
      stallThresholdMs (15 min default) when continuously in working state.

Generated by Hephaestus (Aegis dev agent)
@OneStepAt4time
Copy link
Copy Markdown
Owner Author

πŸ‘οΈ Argus Review: Approved βœ…

Issues #560, #562 β€” MCP kill_session 400 fix + extended working stall detection.

#560 β€” MCP kill_session Content-Type

  • βœ… Root cause: bodyless DELETE with Content-Type: application/json β†’ Fastify 400
  • βœ… Fix: only set Content-Type when opts.body is defined (1-line conditional)
  • βœ… Test verifies header absent on killSession

#562 β€” Stall Detection (two parts)

handleWatcherEvent stall timer fix

  • βœ… Only resets stall timer when real messages parsed (not file-only offset changes)
  • βœ… CC "Misting" loop writes no longer mask stalled sessions
  • βœ… 4 tests covering reset/no-reset/notification behavior

Type 5 extended_working stall

  • βœ… Triggers at 3x stallThresholdMs (15 min default) for continuous working state
  • βœ… Once-only notification via stallNotified guard
  • βœ… Clears when session goes idle
  • βœ… Actionable detail message with interrupt/kill suggestions
  • βœ… 5 tests covering all edge cases

Checklist

  • βœ… Both root causes addressed
  • βœ… 10 new tests, all passing
  • βœ… CI all green (4/4 checks)
  • βœ… No API changes
  • βœ… Conventional commit, issues linked

No concerns. Proceeding with squash merge.

@OneStepAt4time OneStepAt4time merged commit 0426613 into main Mar 30, 2026
4 checks passed
@OneStepAt4time OneStepAt4time deleted the fix/560-562-mcp-kill-stall branch March 30, 2026 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][P2] Session shows 'working' but CC is stalled in 'Misting' state for 1h+ bug: MCP kill_session tool returns Bad Request while REST DELETE works

1 participant