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
- Start OpenCode TUI session
- Request AI to write a file with 150+ lines of content
- Observe TUI freezing at "Preparing to write..."
- 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)
- Use
edit tool instead of write for incremental changes
- Write files in smaller chunks
- Set
"scroll_acceleration": { "enabled": false } in config (marginal improvement)
Summary
The TUI freezes indefinitely on "Preparing to write..." when the
writeorbashtool receives large content (150+ lines). Small content (1-2 lines) works fine.Environment
Reproduction Steps
Works:
writewith 1-10 lines of contentHangs:
writewith 150+ lines of contentSame behavior:
bashwith large heredoc/content in parametersRoot 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, themetadatafield has no size constraint:2. TUI renders entire diff synchronously
In
packages/tui/src/routes/session/permission.tsx(EditBody component):The
<diff>component from@opentui/coreparses the entire diff synchronously, blocking the event loop when content is large.3. Existing limits don't protect against this
tool-output-store.tsbash.tsLog Evidence
From
%TEMP%\oh-my-opencode.log: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_sizeconfig optionSimilar 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)
edittool instead ofwritefor incremental changes"scroll_acceleration": { "enabled": false }in config (marginal improvement)