Skip to content

TUI hangs on 'Preparing to write...' with large file content (unbounded diff rendering) #31916

@caramaschiHG

Description

@caramaschiHG

Summary

The TUI freezes indefinitely on "Preparing to write..." when the write or bash tool receives large content (150+ lines). Small content (1-2 lines) works fine.

Environment

  • OS: Windows 11
  • OpenCode Version: 1.17.3 (npm global install)
  • Terminal: TUI mode
  • Plugin: oh-my-openagent@latest

Reproduction Steps

  1. Start OpenCode TUI session
  2. Request AI to write a file with 150+ lines of content
  3. Observe TUI freezing at "Preparing to write..."
  4. The operation never completes (requires manual termination)

Works: write with 1-10 lines of content
Hangs: write with 150+ lines of content
Same behavior: bash with large heredoc/content in parameters

Root Cause Analysis

The hang occurs in the permission rendering layer, not in tool execution:

1. Permission metadata includes unbounded diff

In packages/core/src/permission.ts, the metadata field has no size constraint:

metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional)

2. TUI renders entire diff synchronously

In packages/tui/src/routes/session/permission.tsx (EditBody component):

<scrollbox height="100%">
  <diff
    diff={diff()}  // ← ENTIRE DIFF, NO SIZE LIMIT
    view={view()}
    ...
  />
</scrollbox>

The <diff> component from @opentui/core parses the entire diff synchronously, blocking the event loop when content is large.

3. Existing limits don't protect against this

Component Limit Protects Permission Rendering?
tool-output-store.ts 50 KB / 2000 lines ❌ No
bash.ts 1 MB per stream ❌ No
Permission diff None This is the gap

Log Evidence

From %TEMP%\oh-my-opencode.log:

[tool-execute-after] Unable to recover stored metadata and no native session linkage was present {"tool":"write",...}

This pattern repeats during hangs, suggesting metadata handling issues with large content.

Proposed Solutions

Option A: Truncate diff in permission metadata

Add a size limit (e.g., 100 KB) when creating permission requests. Show truncation notice in UI.

Option B: Add max_diff_size config option

Similar to existing tool_output.max_bytes, allow users to configure:

{
  "permission": {
    "max_diff_size": 102400
  }
}

Option C: Async/lazy diff rendering

Render diff asynchronously or implement lazy-loading for large diffs in the permission dialog.

Related Issues

Workarounds (Current)

  1. Use edit tool instead of write for incremental changes
  2. Write files in smaller chunks
  3. Set "scroll_acceleration": { "enabled": false } in config (marginal improvement)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions