anthropics / anthropics/claude-code
Monitor with persistent: true is capped at 30 minutes since 2.1.26x ("expires in 30m unless the source ends first")
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
## Summary
Since around 2.1.268 (still on 2.1.272), a Monitor armed with `persistent: true` is capped at 30 minutes. The tool result reads:
> Monitor started (task …, expires in 30m unless the source ends first; you get one notice at expiry — re-arm if you still need the watch).
and 30 minutes later the watch is killed with `[Monitor expired after 30m …]`. The documented behaviour, and what the same session saw earlier in September, is that a persistent Monitor runs until the session ends or `TaskStop` is called, with `timeout_ms` ignored. Nothing in the changelog for 2.1.257 to 2.1.272 mentions a 30-minute limit; 2.1.257 actually removed a one-hour limit on subagents' background commands.
## Reproduce
1. Interactive session, Linux (Arch), Claude Code 2.1.272 (also 2.1.268).
2. Have the model arm any long-running, stdout-emitting command, e.g. a mailbox poller:
`Monitor({command: "python3 watch.py --interval 180", description: "new mail", persistent: true, timeout_ms: 3600000})`
3. The tool result says "expires in 30m"; after 30 minutes the expiry notice arrives and the watch is gone.
## Expected
A persistent watch runs for the session; no 30-minute expiry. `timeout_ms: 3600000` should at least be honoured.
## Why this matters
A watch for an external event (mail, a webhook, a queue) has no natural end. With the cap, the model must re-arm every 30 minutes: each re-arm is a model turn and a tool call, and events that land between expiry and re-arm are missed. Over a working day that is dozens of pointless turns and real gaps in coverage. It also makes the `persistent` flag misleading, since the tool accepts it and then ignores it.
## Checks done
- `~/.claude/settings.json`, `settings.local.json` and `policy-limits.json` contain nothing monitor-related.
- Reproduced across a machine restart and a Claude Code update (2.1.268 → 2.1.272).
- Not the low-memory guard: that stops background commands with a different message ("running low on memory"), and Monitors were killed at exactly 30 minutes with the box idle.
## Ask
Restore the documented persistent behaviour, or, if a cap is intended, make it configurable (a setting or a documented environment variable) and state it in the tool description and the changelog.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the issue with the documented Monitor command and a long-running stdout-emitting command, then compare the observed 30-minute expiry with the expected persistent behavior. Done means persistent watches run until the session ends or TaskStop, or an intended cap is configurable and documented in the tool description and changelog.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100