anthropics / anthropics/claude-code

Subagent spawn records carry no status or lifecycle timestamps, so orphaned background agents display as "running" indefinitely — including across a reboot

Open
#94,872 0 comments 0 reactions 0 assignees View on GitHub
area:agent-view area:agents bug has repro platform:linux
Dominant language
Python
Stars
145k
Forks
23.1k
PR merge metrics
PR metrics pending

Description

## Preflight Checklist

- [x] I have searched existing issues for similar behavior reports
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
- [x] This report does NOT contain sensitive information

Related but distinct: #75314 and #68992 report background tasks stuck "Running" with no way to cancel. This report is about the persistence mechanism rather than the cancellation UX, and identifies a concrete schema cause. Filing separately because the fix is different; happy to have it merged if maintainers prefer.

## What's Wrong?

A background subagent whose parent session exits leaves behind a spawn record that is never marked finished. Anything that derives task state from those records reports the agent as still running, with an elapsed time that grows without bound.

The decisive symptom: a task displayed as "running for 500 hours" roughly three hours after a full system reboot. No process survives a reboot, so the display cannot reflect anything live.

The cause is in the record itself. Every subagent spawn writes a small metadata file under:

~/.claude/projects///subagents/agent-.meta.json

I inspected all 757 of these on one machine. **Not one contains a status field, a start timestamp, or a completion timestamp.** The complete schema is:

{
"agentType": "general-purpose",
"description": "...",
"toolUseId": "toolu_...",
"spawnDepth": 1,
"requestShape": "background",
"requestNonInteractive": true
}

With no lifecycle fields, liveness can only be inferred from the absence of a completion record, and elapsed time can only be computed from file modification time. Both are wrong once the parent process is gone.

This is not specific to any plugin, despite how it tends to surface. Distribution across the 757 records on this machine:

| agentType | records |
|---|---|
| general-purpose | 567 |
| (a plugin-provided agent type) | 138 |
| Explore | 36 |
| claude | 8 |
| fork | 4 |
| Plan | 3 |
| claude-code-guide | 1 |

The built-in `general-purpose` type accounts for four times more stale records than the plugin type that first drew attention. 750 of the 757 records predate the current boot, so by the display's own logic every one of them is "running". The oldest is 832 hours old.

Very likely the same root cause as a second symptom seen on the same machine: on a session restart, 14 background tasks were reported with "No completion record was found for them in the previous session ... They have been marked stopped." Spawn is recorded; completion is not.

## What Should Happen?

Either of these would fix it, and the first is cheaper:

1. Bound the elapsed-time display by process liveness and by boot time. A record whose owning process is gone, or whose start precedes the current boot, cannot be running and should not be displayed as such.
2. Write a terminal state into the record when an agent completes, fails, or is orphaned, so task views read state rather than infer it. A `status` plus `startedAt`/`endedAt` would also make the 14-orphans-on-restart message exact instead of a guess.

A cleanup path for records that can no longer correspond to a live process would prevent the unbounded accumulation (757 records here, 99% of them stale).

## Error Messages/Logs

No error is emitted. The failure is silent and presents as a plausible-looking runtime.

Observed on one machine:

$ uptime -s
2026-09-16 14:08:23 # ~3 hours before inspection

# every spawn record, searched for any lifecycle field:
$ grep -l '"status"\|"startedAt"\|"completedAt"\|"started_at"' \
~/.claude/projects/*/*/subagents/*.meta.json | wc -l
0

# records total, and records predating this boot:
757 total
750 predating boot

# oldest record
2026-08-13 (832 hours)

## Steps to Reproduce

1. Spawn a subagent with the Agent tool as a background request.
2. End the parent session before it completes, or reboot the machine.
3. Inspect `~/.claude/projects///subagents/agent-.meta.json`. It persists with no completion marker and no timestamps.
4. Any view deriving task state from these records shows the agent as running, with elapsed time growing indefinitely and unaffected by reboots.

## Claude Model

Not model-dependent. Reproduced with records spanning several agent types and models.

## Environment

- Claude Code 2.1.273, Linux, terminal CLI.
- Long-lived multi-agent workstation; many background subagents spawned over several weeks.

## Regression

Unknown. The oldest affected record on this machine is from 13 August, so the behavior predates that date.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by tracing how Agent background requests write and how task views derive state from ~/.claude/projects///subagents/agent-.meta.json. Reproduce the orphaned-record case by ending the parent session or rebooting, then inspect the related task-state and restart handling. Done means orphaned agents no longer appear as running indefinitely and elapsed time is not inferred incorrectly from stale records.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.