ui.matches/string waitFor hangs the run when screen() hits OpenTUI OutputBusy

Aperta Adatta ai principianti
#142 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
69/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
testing

Direzione di ricerca

Inizia da packages/simulation/src/frontend/actions.ts, dove l’issue indica screen() e matches() come il percorso che non funziona; confrontalo con il percorso di attesa dell’inattività del rendering usato da ui.capture. Riproduci il problema con le due chiamate consecutive a ui.waitFor() descritte nell’issue e verifica che l’endpoint di simulazione risponda in caso di errore durante la lettura del buffer. Il lavoro è completato quando matches attende che il rendering sia inattivo e gli errori restituiscono una risposta invece di lasciare l’RPC senza risposta.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Summary

ui.matches (and therefore ui.waitFor("some text"), which polls it) can fail permanently on a current V2 checkout:

opencode drive ui websocket: request failed cause="NativeError: ot_session_acquire_buffer_lease failed: OutputBusy"
    at withResolvedChars (@opentui/core buffer.ts)
    at screen (packages/simulation/src/frontend/actions.ts:94)
    at matches (packages/simulation/src/frontend/actions.ts:150)

The simulation endpoint logs the failure and never answers the RPC, so Drive waits until UiTimeoutError (30s) and aborts the run. matches calls screen() (a direct currentRenderBuffer.getRealCharBytes() read) without waiting for the renderer to go idle, so it races a render that holds the buffer lease. ui.capture re-renders and waits for idle() first, and did not fail in 6+ consecutive calls in the same run.

The first matches usually succeeds and a later one fails, so a waitFor that has already matched once can still die mid-poll.

Reproduction

yield* ui.submit("Run something")
yield* ui.waitFor("step 3", { timeout: 30_000 })  // may succeed
yield* ui.waitFor("step 4", { timeout: 30_000 })  // UiTimeoutError: ui.matches timed out after 30000ms

100% reproducible across 3 runs on this checkout, with recording: false.

Expected

  • The simulation endpoint answers the RPC with an error (or retries internally) instead of leaving it unanswered; a failed read should surface as a catchable UiWaitTimeoutError/operation error, not hang the whole run.
  • matches/screen should use the same render-idle path as capture.

Environment

  • opencode-drive 2.4.0
  • OpenCode b032f90634 (PR #62977 worktree), @opentui/core 0.8.1
  • TUI stderr/log: /tmp/opencode-drive/run-af7b2256-d917-4337-b2cd-c92c25a62afb/logs/opencode/log/opencode-local.log (search OutputBusy)

Workaround

Poll ui.capture() and search the joined span text yourself (what I did for the recording), instead of ui.matches/string waitFor.

Lingua principale
TypeScript
Stelle
41
Fork
9
Merge medio
39m
PR unite (30g)
9

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di anomalyco/opencode-drive

Tutte le issue di anomalyco/opencode-drive

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.