Skip to content

session: first-turn subtask command leaves parent session empty and untitled #52468

Open

Description

@raaish

Description

Invoking a subtask: true slash command as the first action in a new session leaves the parent session with zero persisted messages, so the desktop app renders it as an empty "Untitled session". The user's prompt and the subagent's tool call exist only in the child session; the parent row never gets a user or assistant message.

After the command, the parent session has:

  • session_v2 row with empty title
  • session_message: 0 rows
  • event_sequence: seq = 11 but event: 0 rows
  • one leftover session_inbox row (type = synthetic, delivery = steer) containing only the plan-mode system-reminder, which is never delivered

The child (subagent) session, by contrast, is fully populated and runs normally.

Plugins

None.

OpenCode version

2.0.21 (channel: latest)

Steps to reproduce

  1. Have a global command that dispatches to a subtask, e.g. ~/.config/opencode/commands/impeccable.md:

    ---
    description: ...
    agent: build
    subtask: true
    ---
    Call skill({ name: "impeccable" }) and follow its `Setup` and `Commands` sections to handle $ARGUMENTS.
  2. Start a new session in Plan mode.

  3. Run the command as the first input, e.g. /impeccable <some arguments>.

  4. Observe the session in the desktop app.

Expected Behavior

The parent session should record the command invocation (and the subagent tool call/result) so the session is visible and usable — or, if subtask sessions are intentionally hidden, the parent should not be left as an empty untitled session with an undelivered inbox item.

Actual Behavior

The parent session contains no messages. The desktop app shows an empty "Untitled session". The only copy of the user's original input is the child subagent's first user message. The child continues running in the background with no visible parent activity.

Additional Context

Verified directly against opencode.db before deleting the session:

session_v2   ses_…  title=''  time_created=1790849318632
session_message (ses_…) count = 0
event_sequence (ses_…) seq = 11   |   event (ses_…) count = 0
session_inbox (ses_…) → [{"text":"<system-reminder>\nYou are in Plan mode…"}]

Child session: parent_id = the empty parent, agent = build, fully populated with messages, actively streaming.

Workaround used: opencode api POST /api/session/<child>/interrupt then opencode session delete <parent> (cascade removed both).

Not reproducible from the CLI alone in my testing; happened through the desktop app. Occurs on the first turn only.

Activity

  1. github-actions commented on Oct 1, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report. I was able to reproduce this on 2.0.21 in the TUI with a simulated model, and it still happens on the latest dev (891a020bc).

    Steps: a project command with agent: build and subtask: true, a new session switched to Plan, then /impeccable some arguments as the first input.

    While the subagent runs, the parent session matches what you saw:

    • title is empty.
    • There are no session_message rows.
    • session_inbox holds one synthetic row containing only the Plan-mode system-reminder.
    • The TUI shows an empty "New session" with only "1 subagent" in the footer.

    The child session is fully populated and runs normally.

    Once the child finishes, the parent does get the reminder, a subagent-completed notification and an assistant reply. But your typed command is never stored in the parent, and the session is never titled.

    The recording and screenshot below show it, and the script below reproduces it.

    recording.mp4

    Screenshot

    Reproduction script (drive.ts)
    // Repro for #52468: a subtask command as the first input leaves the parent session empty.
    import { Effect, Stream } from "effect"
    import { Llm, OpenCodeDriver } from "opencode-drive"
    
    export default OpenCodeDriver.use(
      {
        ...(process.env.OC_DEV ? { opencode: { dev: process.env.OC_DEV } } : {}),
        tui: { recording: true },
        project: {
          git: true,
          files: {
            ".opencode/commands/impeccable.md":
              "---\ndescription: Impeccable subtask\nagent: build\nsubtask: true\n---\nSay hello and handle $ARGUMENTS.\n",
          },
        },
      },
      ({ ui, llm }) =>
        Effect.gen(function* () {
          yield* llm.serve(() => Stream.make(Llm.pause(20000), Llm.text("CHILD-REPLY: hello from the subagent")))
          yield* Effect.sleep(1500)
          yield* ui.press("tab", { shift: true })
          yield* Effect.sleep(800)
          yield* ui.screenshot("home-plan")
          yield* ui.type("/impeccable some arguments")
          yield* Effect.sleep(800)
          yield* ui.screenshot("typed")
          yield* ui.enter()
          yield* Effect.sleep(8000)
          yield* ui.screenshot("while-subagent-runs")
          yield* Effect.sleep(20000)
          yield* ui.screenshot("after-subagent-finished")
        }),
    )

    Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions