Skip to content

bg output fails while a timeout-promoted command is still Running (output artifact created only at completion) #1189

Description

@ianalitis

Upstream: https://github.com/1jehuang/jcode
Source commit: 1b99ae621 (upstream master, 2026-09-06)
Binary identity: jcode v0.83.71-dev (10a4f385a), local branch on top of master
Platform: macOS 26.6.2, arm64

Summary

When a foreground bash call exceeds its timeout and Jcode promotes it to a background task,
the task's .output artifact is not created until the command finishes. bg output <id> during
the Running state returns Output not found for task, so an agent cannot inspect partial output of
exactly the commands it most needs to watch (long builds, tests, uploads).

The status artifact is written immediately with pid: null; only the output artifact is missing.

Reproduction (two live receipts, 2026-09-07)

Tool call: bash with command: "echo start; sleep 20; echo done", timeout: 2000.

  1. Jcode reports "exceeded the foreground timeout after 2.0s and is continuing in background",
    task 836444a36r.
  2. Immediately, bg output 836444a36r returns
    Error: Output not found for task: 836444a36r. Task may not exist or output file was deleted.
  3. Filesystem at the same moment ($TMPDIR/jcode-bg-tasks/):
    • 836444a36r.status.json exists, "status": "running", "pid": null
    • 836444a36r.output does not exist
  4. After completion the output file appears with the full content.

An earlier receipt on 2026-08-31 with v0.81.5-dev (422da2bc0) showed the same behavior.

Why the regression test misses it

crates/jcode-app-core/src/tool/bash_tests.rs::test_foreground_timeout_promotes_and_command_keeps_running
waits for BackgroundTaskStatus::Completed before calling background::global().output(&task_id).
It never reads the output while the task is Running, so the gap is not covered.

Expected

Promotion creates an empty retained output artifact before returning the task id, so
bg output succeeds (possibly empty) while Running, and the wrapper replaces it with the
complete output at termination. pid: null is fine for the in-process adoption path.

Suggested test change

In the existing test, after promotion and before waiting for completion, assert
background::global().output(&task_id).is_some(). It is red today.

Workaround in use

Start commands expected to outlive the timeout with run_in_background: true and consume them
through bg; do not rely on automatic promotion for anything whose partial output matters.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    autonomous: clearHands-off: unambiguous bug, obvious fix, no decisions. Don't even look - an agent can fully solve.bugSomething isn't workingtriage: reproducibleClear repro + clear fix path

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions