coder / coder/ghostty-web

Hyperlink arena exhaustion (StringAllocOutOfMemory) spins the write path instead of degrading

Open
#186 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
2.8k
Forks
172
PR merge metrics
No merged PRs in 30d

Description

## Summary

When the terminal's hyperlink string arena is exhausted, the write path appears to **spin / not make forward progress** instead of dropping the hyperlink and continuing. Writing a large, OSC 8-dense buffer in one shot floods this warning and then pins the thread:

```
warning(terminal): error reallocating for more hyperlink space, ignoring hyperlink err=error.StringAllocOutOfMemory
```

The `ignoring hyperlink` wording suggests the intent is to degrade gracefully, but in practice the containing write does not return.

## Environment

- `ghostty-web@^0.4.0`, running as WASM in an Electron renderer (embedded by [Nimbalyst](https://github.com/nimbalyst/nimbalyst)).
- Trigger: replaying a terminal's saved scrollback (~500 KB, very hyperlink-dense — Claude Code / Codex emit many OSC 8 clickable file paths) into the terminal in a single write on session restore.

## Observed behavior

- A burst of ~70 identical `StringAllocOutOfMemory` hyperlink warnings within ~7 ms, then silence.
- The renderer's main thread then sits at ~100% of one core with **0 syscalls over a 6 s `strace` sample** — i.e. a pure userspace loop, not I/O or a lock.
- A paused JS stack shows the top frame inside the WASM `invoke` trampoline — control went into the terminal write and never came back.

So once the arena is full, processing the remaining OSC 8 sequences in that write seems to loop rather than skip-and-advance.

## Question / hypothesis

- Is hyperlink-arena exhaustion expected to be recoverable **within a single `terminal.write`**? It looks like the post-failure "ignoring hyperlink" path may retry the allocation (or fail to advance the parser) when the arena stays full for the *next* hyperlink in the same write, turning many consecutive OSC 8 sequences into an unbounded loop.
- Could you point me to where `StringAllocOutOfMemory` from the hyperlink path is handled? If the fix is "drop the hyperlink, advance, and don't re-attempt until space frees", that would turn this from a hang into graceful degradation.

## Caveats

I don't yet have a standalone `ghostty-web` reproduction — this was diagnosed through the Nimbalyst embedding (traces above). If a minimal repro would help, I can try to build one that writes a synthetic OSC 8-dense buffer larger than the arena in a single call; a pointer to the arena size / relevant source would speed that up.

Filing here since `ghostty-web` owns the WASM build; if this is upstream Ghostty behavior, happy to move it.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.