Skip to content

TUI: dialog-execute.tsx mutates dialog state during render #56137

Closed as not planned

Description

@Addin

Summary

dialog-execute.tsx calls dialog.setSize(), dialog.setCentered(), and executeCode() during the render body — mutating shared global dialog state mid-render.

Root cause

packages/tui/src/routes/session/dialog-execute.tsx:40-44:

dialog.setSize("xlarge")
dialog.setCentered(true)

const code = createMemo(() => executeCode(props.part.state.input))  // <-- side effect

Suggested fix

Move dialog.setSize()/dialog.setCentered() to onMount. Avoid calling executeCode() during render.

Activity

  1. opencode-agent commented on Oct 16, 2026

    @opencode-agent
    Contributor

    Thanks for the report! Before we can act on it, we need to know what actually goes wrong for a user. Looking at the code on dev:

    • executeCode() is a pure helper. It only reads input.code from the tool input and returns it, so calling it inside createMemo has no side effect and doesn't run any code.
    • In Solid, a component body is setup code that runs once, not on every render. So dialog.setSize("xlarge") and dialog.setCentered(true) set the dialog store once when the dialog opens. Several other dialogs set their size the same way.

    If you saw an actual problem, could you share:

    • The output of opencode --version, your OS and your terminal
    • What you did, e.g. opened the execute tool's details from a session
    • What you expected and what happened instead, e.g. the wrong dialog size, flicker, or an error or warning, with a screenshot or log if you have one

    You can reply here with the details or edit the issue. If you edit it, please also leave a comment saying you've updated it, so we know when you're done.

    You opened similar reports about other dialog files at the same time, so the same question applies to them:

  2. Addin commented on Oct 16, 2026

    @Addin
    Author

    This was found via source code review of packages/tui/src/routes/session/dialog-execute.tsx:40-44. While Solid component bodies run once and dialog.setSize() just writes to a store, this pattern is inconsistent with other dialogs that use onMount (e.g. dialog-session-list.tsx:194, dialog-integration.tsx:518, dialog-workspaces.tsx:55). The concern is maintainability and correctness as the code evolves - if dialog.setSize() ever needs to be reactive or if additional logic is added, calling it during render body could cause subtle bugs. No visible problem observed today, but it's a cleanup/consistency issue worth addressing together with the related issues (#56136, #56138, #56139, #56140, #56141, #56142, #56144, #56145).

  3. opencode-agent commented on Oct 16, 2026

    @opencode-agent
    Contributor

    Thanks for clarifying! I'll treat this as a cleanup request rather than a bug: dialogs should set their size and centering the same way, instead of some using onMount and others calling dialog.setSize()/setCentered() in the component body.

    You're right that both patterns are in use on dev. dialog-session-list, dialog-integration, dialog-workspaces and the plugins dialog use onMount, while dialog-execute, dialog-skill, dialog-debug, dialog-pair, dialog-image-preview, dialog-shell-output and a few others call these directly in the component body. (executeCode() itself is a pure helper, so that part isn't a concern.)

    One thing to watch out for in dialog-execute: its height memo reads dialog.size straight away, and a comment there says sizing synchronously keeps the dialog from growing over several frames when it opens. Moving setSize to onMount could lay out the first frame at the previous size, so a shared approach might be better than onMount everywhere.

    The maintainers will consider it, probably as one cleanup together with your related reports (#56136, #56138–#56145). There's no commitment on whether or when.

  4. neriousy commented on Oct 20, 2026

    @neriousy
    Member

    Thanks for reviewing the code. You confirmed that no visible problem occurs, and executeCode only reads the supplied code text. We're closing this cleanup request; if you encounter an actual failure, please share the steps and impact.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions