fix(background-agent): queue fallback notification when parent notification delivery fails (fixes #2627)#3448
Conversation
…cation delivery fails (fixes code-yeongyu#2627)
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80e47921c6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| log("[background-agent] Error in notifyParentSession, queuing fallback:", { taskId: task.id, error: err }) | ||
| this.queuePendingNotification( | ||
| task.parentSessionID, | ||
| `[Background task completed] "${task.description}" (agent: ${task.agent ?? "unknown"}) finished but notification delivery failed. Use background_output to retrieve the result.\n\nSession ID: ${task.sessionID}\nTask ID: ${task.id}`, |
There was a problem hiding this comment.
Wrap fallback completion notice in tags
When enqueueNotificationForParent(...notifyParentSession...) rejects, this path queues a plain-text fallback instead of the standard reminder format from buildBackgroundTaskNotificationText (<system-reminder>...</system-reminder>). In the exact failure scenario this commit targets, agents that follow the documented rule to wait for a <system-reminder> before calling background_output (for example in src/agents/sisyphus/default.ts) can miss this fallback and keep waiting. Use the same tagged notification format for the queued fallback so behavior stays consistent with normal delivery.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
1 issue found across 1 file
Confidence score: 3/5
- There is a concrete regression risk in
src/features/background-agent/manager.ts: the fallback notification path emits plain text ([Background task completed] ...) instead of the expected<system-reminder>...</system-reminder>format. - Because severity/confidence are both moderate (6/10) and this affects notification shape, downstream consumers that rely on tagged reminders may mis-handle or ignore fallback messages.
- Pay close attention to
src/features/background-agent/manager.ts- fallback and normal notification builders should stay format-consistent to avoid user-facing notification/parsing issues.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/features/background-agent/manager.ts">
<violation number="1" location="src/features/background-agent/manager.ts:1710">
P2: The fallback notification text uses a plain-text format (`[Background task completed] ...`) instead of the `<system-reminder>...</system-reminder>` tag format that the normal notification path produces via `buildBackgroundTaskNotificationText`. Agents that parse for `<system-reminder>` tags to detect task completion (e.g., before calling `background_output`) will not recognize this fallback, potentially leaving the parent session stuck — defeating the purpose of this fix. Use `buildBackgroundTaskNotificationText` (or at minimum wrap the message in `<system-reminder>` tags) so the fallback is consistent with normal delivery.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| log("[background-agent] Error in notifyParentSession, queuing fallback:", { taskId: task.id, error: err }) | ||
| this.queuePendingNotification( | ||
| task.parentSessionID, | ||
| `[Background task completed] "${task.description}" (agent: ${task.agent ?? "unknown"}) finished but notification delivery failed. Use background_output to retrieve the result.\n\nSession ID: ${task.sessionID}\nTask ID: ${task.id}`, |
There was a problem hiding this comment.
P2: The fallback notification text uses a plain-text format ([Background task completed] ...) instead of the <system-reminder>...</system-reminder> tag format that the normal notification path produces via buildBackgroundTaskNotificationText. Agents that parse for <system-reminder> tags to detect task completion (e.g., before calling background_output) will not recognize this fallback, potentially leaving the parent session stuck — defeating the purpose of this fix. Use buildBackgroundTaskNotificationText (or at minimum wrap the message in <system-reminder> tags) so the fallback is consistent with normal delivery.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/features/background-agent/manager.ts, line 1710:
<comment>The fallback notification text uses a plain-text format (`[Background task completed] ...`) instead of the `<system-reminder>...</system-reminder>` tag format that the normal notification path produces via `buildBackgroundTaskNotificationText`. Agents that parse for `<system-reminder>` tags to detect task completion (e.g., before calling `background_output`) will not recognize this fallback, potentially leaving the parent session stuck — defeating the purpose of this fix. Use `buildBackgroundTaskNotificationText` (or at minimum wrap the message in `<system-reminder>` tags) so the fallback is consistent with normal delivery.</comment>
<file context>
@@ -1704,8 +1704,11 @@ export class BackgroundManager {
+ log("[background-agent] Error in notifyParentSession, queuing fallback:", { taskId: task.id, error: err })
+ this.queuePendingNotification(
+ task.parentSessionID,
+ `[Background task completed] "${task.description}" (agent: ${task.agent ?? "unknown"}) finished but notification delivery failed. Use background_output to retrieve the result.\n\nSession ID: ${task.sessionID}\nTask ID: ${task.id}`,
+ )
}
</file context>
Summary
Problem
Parent sessions get permanently stuck showing "waiting for background agents" when notification delivery fails. In
tryCompleteTask, the task status is atomically set tocompletedbefore the parent notification is sent. IfnotifyParentSessionthrows (timeout, transient error), the parent session never learns the task finished. SincepollRunningTasksskips non-running tasks, no retry is attempted and the parent hangs indefinitely.Fix
When
notifyParentSessionfails, the catch block now callsqueuePendingNotificationto inject a fallback notification into the parent session's next chat message. This ensures the parent always learns about task completion, even if the direct notification mechanism fails.Changes
src/features/background-agent/manager.tstryCompleteTaskcatch block instead of silently dropping the errorFixes #2627
Summary by cubic
Ensures parent sessions always learn when a background task completes by queuing a fallback notification if direct delivery fails. Prevents sessions from getting stuck on "waiting for background agents" (fixes #2627).
tryCompleteTask, catchnotifyParentSessionerrors and callqueuePendingNotificationto inject a completion message into the parent’s next chat.Written for commit 80e4792. Summary will update on new commits.