Skip to content

Heartbeat prompt injected into cron runs targeting non-cron session keys #53061

@aneym

Description

@aneym

Summary

When a cron job has sessionTarget: "isolated" but targets a non-cron session key (e.g. agent:main:kos:thread:... or agent:main:kos:space:...), the heartbeat prompt ("Read HEARTBEAT.md...") is injected into the system prompt. The agent then reads HEARTBEAT.md and responds with unrelated tasks, polluting the thread/space.

Root Cause

In src/agents/pi-embedded-runner/run/attempt.ts at line ~1651:

heartbeatPrompt: isDefaultAgent
  ? resolveHeartbeatPrompt(...)
  : undefined,

isDefaultAgent is true because the session key resolves to agent:main (the default agent). resolvePromptModeForSession() returns "full" because isCronSessionKey() checks for a cron: prefix in the session key rest — but kOS thread/space keys use kos:thread:... / kos:space:..., so they don't match.

The params.trigger value IS "cron" (passed from cron/isolated-agent/run.ts:603), but it's never checked at the heartbeat injection site.

Proposed Fix

heartbeatPrompt: isDefaultAgent && params.trigger !== "cron"
  ? resolveHeartbeatPrompt(...)
  : undefined,

This suppresses heartbeat injection for all cron-triggered embedded agent runs, regardless of session key shape.

Workaround

Set agents.defaults.heartbeat.session: "main" in config to pin heartbeat runs to agent:main:main.


Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions