claude-code - 💡(How to fix) Fix Agent Teams: SendMessage writes mailbox JSON without `type` field → reader UI shows 'Unhandled case: [object Object]'

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Khi sử dụng Agent Teams feature (TeamCreate + SendMessage), tool SendMessage ghi message vào mailbox JSON files (~/.claude/teams/<team>/inboxes/*.json) thiếu field type. Sau khi quit + reopen Cursor/VSCode, reader UI load message từ disk → render fail → popup error "Unhandled case: [object Object]" hiện mỗi lần extension poll mailbox (~100ms interval).

Error Message

Khi sử dụng Agent Teams feature (TeamCreate + SendMessage), tool SendMessage ghi message vào mailbox JSON files (~/.claude/teams/<team>/inboxes/*.json) thiếu field type. Sau khi quit + reopen Cursor/VSCode, reader UI load message từ disk → render fail → popup error "Unhandled case: [object Object]" hiện mỗi lần extension poll mailbox (~100ms interval). Missing type field. Reader expects type, gets undefined → fallback → [object Object] error popup. 3. Schema validation on write: throw error if required fields missing — surface bug at write time, not read time

Root Cause

Khi sử dụng Agent Teams feature (TeamCreate + SendMessage), tool SendMessage ghi message vào mailbox JSON files (~/.claude/teams/<team>/inboxes/*.json) thiếu field type. Sau khi quit + reopen Cursor/VSCode, reader UI load message từ disk → render fail → popup error "Unhandled case: [object Object]" hiện mỗi lần extension poll mailbox (~100ms interval).

Fix Action

Workaround

Client-side hook that runs on SessionStart, scans all team inboxes, injects "type": "message" for messages missing the field. Idempotent.

Sample Node.js script:

const fs = require('fs'), path = require('path'), os = require('os');
const TEAMS_DIR = path.join(os.homedir(), '.claude', 'teams');
if (!fs.existsSync(TEAMS_DIR)) process.exit(0);

for (const team of fs.readdirSync(TEAMS_DIR)) {
  const inboxDir = path.join(TEAMS_DIR, team, 'inboxes');
  if (!fs.existsSync(inboxDir)) continue;
  for (const f of fs.readdirSync(inboxDir).filter(x => x.endsWith('.json'))) {
    const fp = path.join(inboxDir, f);
    const data = JSON.parse(fs.readFileSync(fp, 'utf8'));
    if (!Array.isArray(data)) continue;
    let patched = 0;
    for (const msg of data) {
      if (typeof msg === 'object' && msg !== null && !msg.type) { msg.type = 'message'; patched++; }
    }
    if (patched > 0) fs.writeFileSync(fp, JSON.stringify(data, null, 2), 'utf8');
  }
}

Register vào .claude/settings.json:

"SessionStart": [{
  "matcher": "",
  "hooks": [{ "type": "command", "command": "node .claude/hooks/inbox-type-patch.cjs" }]
}]

Code Example

Agent Teams: SendMessage writes mailbox JSON without `type` field → reader UI shows "Unhandled case: [object Object]"

---

[
  {
    "from": "team-lead",
    "text": "...",
    "summary": "...",
    "timestamp": "2026-05-16T...",
    "read": true
  }
]

---

[inProcessRunner] tester poll #53842: checking mailbox
[TeammateMailbox] readMailbox: read 64 message(s)
[TeammateMailbox] readUnreadMessages: 0 unread of 64 total

---

const fs = require('fs'), path = require('path'), os = require('os');
const TEAMS_DIR = path.join(os.homedir(), '.claude', 'teams');
if (!fs.existsSync(TEAMS_DIR)) process.exit(0);

for (const team of fs.readdirSync(TEAMS_DIR)) {
  const inboxDir = path.join(TEAMS_DIR, team, 'inboxes');
  if (!fs.existsSync(inboxDir)) continue;
  for (const f of fs.readdirSync(inboxDir).filter(x => x.endsWith('.json'))) {
    const fp = path.join(inboxDir, f);
    const data = JSON.parse(fs.readFileSync(fp, 'utf8'));
    if (!Array.isArray(data)) continue;
    let patched = 0;
    for (const msg of data) {
      if (typeof msg === 'object' && msg !== null && !msg.type) { msg.type = 'message'; patched++; }
    }
    if (patched > 0) fs.writeFileSync(fp, JSON.stringify(data, null, 2), 'utf8');
  }
}

---

"SessionStart": [{
  "matcher": "",
  "hooks": [{ "type": "command", "command": "node .claude/hooks/inbox-type-patch.cjs" }]
}]
RAW_BUFFERClick to expand / collapse

GitHub Issue Draft — Agent Teams SendMessage type field bug

Target repo: anthropics/claude-code

Submit URL: https://github.com/anthropics/claude-code/issues/new


Title

Agent Teams: SendMessage writes mailbox JSON without `type` field → reader UI shows "Unhandled case: [object Object]"

Body (paste as-is)

Summary

Khi sử dụng Agent Teams feature (TeamCreate + SendMessage), tool SendMessage ghi message vào mailbox JSON files (~/.claude/teams/<team>/inboxes/*.json) thiếu field type. Sau khi quit + reopen Cursor/VSCode, reader UI load message từ disk → render fail → popup error "Unhandled case: [object Object]" hiện mỗi lần extension poll mailbox (~100ms interval).

Environment

  • Claude Code VSCode extension (cũng affects Cursor — same extension)
  • Extension version: cc_version=2.1.141.x (per log header)
  • OS: Windows 11
  • Feature flag: env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1

Reproduction steps

  1. Enable Agent Teams: set env CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 in ~/.claude/settings.json, restart Cursor
  2. Use natural language to create team: "Create an agent team test-team with planner/tester/fixer"
  3. Run normal validation/coding work for ~1 hour — SendMessage gets called many times
  4. Quit Cursor without calling TeamDelete (or without sending shutdown_request)
  5. Wait some time (next day OK) — make sure Cursor fully restarted, not just reload
  6. Reopen workspace
  7. Result: popup "Unhandled case: [object Object] · View output logs · Troubleshooting resources" appears, recurring rapidly

Expected behavior

Either:

  • (a) SendMessage writes message JSON với type: "message" field, OR
  • (b) Reader UI gracefully handles missing type field (fallback to "message" type)

Currently neither happens.

Actual behavior

Inbox JSON structure (~/.claude/teams/<team>/inboxes/<agent>.json):

[
  {
    "from": "team-lead",
    "text": "...",
    "summary": "...",
    "timestamp": "2026-05-16T...",
    "read": true
  }
]

Missing type field. Reader expects type, gets undefined → fallback → [object Object] error popup.

Evidence

In our team fpa-validation: 79/79 messages across 8 inbox files missing the type field:

  • team-lead.json: 64 messages
  • tester.json: 6 messages
  • planner.json: 4 messages
  • tester-sm135.json, planner-sm135.json, fixer-sm135.json, tester-2.json, fixer.json: rest

Output log excerpt (high-frequency polling)

[inProcessRunner] tester poll #53842: checking mailbox
[TeammateMailbox] readMailbox: read 64 message(s)
[TeammateMailbox] readUnreadMessages: 0 unread of 64 total

Polling happens every ~100ms across 4 teammates. Counter reached #56472 after several hours = ~564,000 mailbox reads → ~564,000 popup spawns.

Why in-session works but cross-restart fails (hypothesis)

  • In-session: extension reads message from in-memory state (which may have type set at runtime by the dispatcher) → renders OK
  • Cross-restart: extension reads message from disk JSON file (persisted without type) → fallback fail

Suggests bug in persistence/serialization layer: writer strips type field when writing to disk, reader expects it when loading from disk. In-memory ↔ disk schema mismatch.

Workaround

Client-side hook that runs on SessionStart, scans all team inboxes, injects "type": "message" for messages missing the field. Idempotent.

Sample Node.js script:

const fs = require('fs'), path = require('path'), os = require('os');
const TEAMS_DIR = path.join(os.homedir(), '.claude', 'teams');
if (!fs.existsSync(TEAMS_DIR)) process.exit(0);

for (const team of fs.readdirSync(TEAMS_DIR)) {
  const inboxDir = path.join(TEAMS_DIR, team, 'inboxes');
  if (!fs.existsSync(inboxDir)) continue;
  for (const f of fs.readdirSync(inboxDir).filter(x => x.endsWith('.json'))) {
    const fp = path.join(inboxDir, f);
    const data = JSON.parse(fs.readFileSync(fp, 'utf8'));
    if (!Array.isArray(data)) continue;
    let patched = 0;
    for (const msg of data) {
      if (typeof msg === 'object' && msg !== null && !msg.type) { msg.type = 'message'; patched++; }
    }
    if (patched > 0) fs.writeFileSync(fp, JSON.stringify(data, null, 2), 'utf8');
  }
}

Register vào .claude/settings.json:

"SessionStart": [{
  "matcher": "",
  "hooks": [{ "type": "command", "command": "node .claude/hooks/inbox-type-patch.cjs" }]
}]

Suggested fix (upstream)

Choose one:

  1. In SendMessage SDK serializer: always inject type: "message" (or whatever type was passed in payload) when serializing message to disk JSON
  2. In reader/renderer: gracefully fallback to type: "message" when undefined
  3. Schema validation on write: throw error if required fields missing — surface bug at write time, not read time

Severity

Medium-High — feature still works in-session, but creates persistent popup spam after any restart with an active team. Workaround easy but should be unnecessary.

Related

  • Tool: SendMessage, TeamCreate, TeamDelete
  • Feature flag: CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS
  • File path: ~/.claude/teams/<team>/inboxes/*.json

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Either:

  • (a) SendMessage writes message JSON với type: "message" field, OR
  • (b) Reader UI gracefully handles missing type field (fallback to "message" type)

Currently neither happens.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Agent Teams: SendMessage writes mailbox JSON without `type` field → reader UI shows 'Unhandled case: [object Object]'