[BUG] Persisted idle signal can starve the event loop before an immediate same-thread run
Describe the Bug
An idle agent signal sent with ifIdle: { behavior: 'persist' }, followed immediately by a new run on the same memory thread, can starve the Node.js event loop indefinitely.
The synthetic persisted-signal run resolves its completion promise before its timer-based active-run cleanup executes. waitForCrossAgentThreadRun can then repeatedly await that already-resolved promise, creating an unbounded microtask loop. Timers and HTTP requests stop progressing while one CPU core remains saturated.
Steps To Reproduce
- Clone the reproduction branch:
git clone --branch repro/persisted-signal-starvation https://github.com/juanmaagd/mastra.git cd mastra - Install dependencies with Node 22 and pnpm:
pnpm install --frozen-lockfile - Run the bounded regression:
pnpm --filter @mastra/core exec vitest run src/agent/__tests__/agent-signals.test.ts -t "allows a run immediately after persisting an idle signal" - Observe that the child process does not exit. The parent watchdog terminates it with
SIGKILLafter 5 seconds.
The fixture subscribes to a thread, persists an idle signal, waits for persistence, and immediately starts a competing run on the same resource/thread pair. It does not call any external model or service.
Link to Minimal Reproducible Example
Expected Behavior
The completed synthetic persisted-signal run should release the thread without starving the event loop. The immediate same-thread run should proceed, timers and HTTP requests should remain responsive, and the process should exit normally.
Environment Information
System:
OS: macOS 26.6.2
CPU: arm64 Apple M5 Pro
Memory: 48 GB
Shell: zsh 5.9
Binaries:
Node: 22.23.0
npm: 10.9.8
pnpm: 11.22.0
npmPackages:
@mastra/core: 1.66.0
@mastra/factory: 0.14.0
@mastra/memory: 1.29.0
@mastra/libsql: 1.22.5
LLM Provider: None; deterministic local LanguageModelV2 test double
Browser: Not applicableVerification
- I have searched the existing issues to make sure this is not a duplicate
- I have included sufficient information for the team to reproduce and understand the issue
Source: mastra-ai/mastra