Skip to content

[Bug]: Completed Python heredoc renders as a large code block instead of a compact command summary #10879

Description

@coygeek

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web, observed in the macOS desktop app.

Summary

A completed, standalone Codex command containing a multiline Python heredoc renders the entire script directly in the chat timeline instead of a compact, expandable command summary such as Ran python3 or Ran 1 command. In the observed case the command succeeded and produced no output. The script becomes a tall, wrapping block with the terminal icon vertically centered beside it and no visible disclosure arrow. Nearby grouped commands still show normal summaries such as Ran 4 commands.

Steps to reproduce

The observed case was recovered from a real session and traced through both the installed app's source maps and current upstream source. The following is a minimized reproduction recipe derived from that evidence; a fresh provider/UI run of this reduced example has not been performed.

  1. Open a Codex conversation in T3 Code desktop.

  2. Have the agent execute one multiline command that succeeds without producing stdout/stderr, for example:

    python3 - <<'PY'
    import json
    from pathlib import Path
    payload = {"example": "value", "items": list(range(20))}
    serialized = json.dumps(payload, indent=2)
    assert serialized
    PY
  3. Have assistant commentary immediately before and after this command so that it forms a standalone completed work entry rather than joining other commands in a group.

  4. Inspect the completed command's default timeline presentation without expanding it. A narrow conversation column makes the effect particularly noticeable.

Expected behavior

Show a compact, single-line summary, for example Ran python3, with an expansion control that reveals the full command. Preserve access to the script even when the command has no output.

Actual behavior

The complete heredoc is used as the visible row label and displayed with preserved newlines and wrapping, taking a large block of vertical space. It resembles raw Python dumped into the conversation, although the persisted event is correctly classified as a command execution.

Impact

Minor bug or occasional failure. Long scripts substantially disrupt timeline readability and push surrounding messages out of view. The observed command itself succeeded.

Version or commit

  • Installed desktop: 0.0.41-nightly.20260909.1426.
  • Packaged t3codeCommitHash: 3e6f856f2359 (full commit: 3e6f856f2359421958a3aa046f2c393e00f3dc6a).
  • The relevant label/expansion condition is also present in upstream main at 08463e2c401ce87858aaaebcb70ed86fb002fb5f.

Environment

macOS 27.0 (26A5425a), T3 Code Nightly desktop, Codex provider, gpt-6-astra, high reasoning effort, /bin/zsh -lc. The screenshot shows the Agents panel open beside a relatively narrow conversation column.

Session evidence

Read-only inspection of the live SQLite store identified the exact command visible in the supplied screenshot:

  • T3 thread: 869f06ab-5437-4948-92d3-907a82fc0580.
  • Tool call: exec-c37fabd1-c5ae-440d-a849-75e0c73b0cd5.
  • Completed activity: c0a6939d-8425-4113-a8d2-1cf1c7e8b037.
  • Completion: 2026-09-09T02:54:21.647Z (September 8, 2026, 7:54:21 p.m. America/Vancouver).
  • kind: "tool.completed", tone: "tool", summary: "Ran command".
  • Payload: itemType: "command_execution", title: "Ran command", status: "completed".
  • data.item.type: "commandExecution", exitCode: 0, aggregatedOutput: null.
  • data.item.command contains a shell-wrapped Python heredoc; the unwrapped script is 410 characters across 7 logical lines.
  • payload.detail is a truncated prefix of that same shell command, ending in ...; it is not output.
  • The script is absent from the persisted assistant messages. Separate assistant messages bracket the command at 02:54:14.882Z and 02:54:27.832Z.

Project paths and unrelated conversation content are omitted from this report.

Source investigation

The installed renderer source map confirms the same conditions below. Links are pinned to the installed build commit:

  1. extractToolCommand / command normalization unwraps /bin/zsh -lc, preserving the full multiline script as entry.command and retaining the wrapped command separately.
  2. extractToolDetail removes the duplicate command detail when there is no actual output. commandDetailRepeatsCommand recognizes truncated command prefixes as echoes.
  3. singleToolCallLabel and workEntryDisplayLabel return the full entry.command. The standalone completed-entry branch uses this label.
  4. In PlainWorkEntryRow, commandMatchesVisibleLabel becomes true. The raw command is excluded from the expansion check by !commandMatchesVisibleLabel, and this successful entry has no output/detail, changed-file metadata, or viewed image. Therefore canExpand is false.
  5. The label class condition explicitly selects whitespace-pre-wrap break-words select-text for commandMatchesVisibleLabel && !canExpand, even with expanded === false. This explains the large block and missing expansion control.

The nearby liveWorkEntryLabel already uses compact verb/program labels. Using consistent compact labeling for completed standalone commands, while keeping the full command in expandable details, appears to address the mismatch.

Suggested regression coverage: a standalone completed multiline command with null/empty output should remain compact and expandable; also check commands with output and multi-command groups.

Related issue

#4076 concerned missing output/repeated commands after expansion and is closed. This report concerns a successful no-output command becoming a full multiline block in the default timeline presentation.

Workaround

No user-facing workaround was verified. No source, app configuration, provider runtime, or live session state was modified during this investigation.

Activity

  1. juliusmarminge commented on Sep 9, 2026

    @juliusmarminge
    Member

    Triage

    Confirmed as a web timeline presentation bug on current main (08463e2). The persisted command event is correct; the collapsed row uses the full heredoc as its label and then disables expansion.

    What I verified

    The source path in the report still matches:

    • singleToolCallLabel / workEntryDisplayLabel return the raw entry.command for standalone completed command rows (MessagesTimeline.logic.ts). That is what the timeline shows by default.
    • liveWorkEntryLabel already compact-labels the same command as Ran ${commandProgramName(...)} (e.g. Ran python3).
    • extractToolDetail correctly drops command-echo detail when there is no stdout/stderr, so this successful no-output case has nothing else to expand.
    • In PlainWorkEntryRow, commandMatchesVisibleLabel is true, canExpand is false, the chevron is hidden, and the label uses whitespace-pre-wrap. That produces the tall wrapping block.

    commandProgramName is already imported in this file and would summarize the reported python3 - <<'PY' command as python3.

    Related

    Mobile uses the same raw-command singleToolCallLabel, but it collapses whitespace and still allows expand when a command exists, so it should not show this tall block.

    Suggested fix

    Do not revert #9267 for short commands. For multiline/long standalone completed commands:

    1. Use the existing compact live label (Ran python3) as the collapsed title.
    2. Keep the full command in the expandable body, including when output is empty.
    3. Do not apply whitespace-pre-wrap on the collapsed row.

    Regression coverage: a standalone completed multiline command with null/empty output stays compact and expandable; also check commands that have output and multi-command groups (Ran N commands).

  2. added
    bugSomething is broken or behaving incorrectly.
    acceptedfeature request accepted
    via-triageFiled through npx t3 triage
    on Sep 9, 2026
  3. juliusmarminge commented on Sep 9, 2026

    @juliusmarminge
    Member

    Fixed by #10981 — collapsed tool-call rows now truncate and stay expandable even when the visible label matches the command text (the heredoc / long no-output case). Closing as resolved.

  4. juliusmarminge commented on Sep 9, 2026

    @juliusmarminge
    Member

    Closing as fixed by #10981.

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

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions