❯_termy
Developerlibtermy

Troubleshooting and validation

Diagnose blank terminals, incorrect incremental updates, input problems, missing replies, and native host shutdown failures.

Begin with the deterministic display-only example for Rust or C. Once it produces the expected cells, introduce the PTY, event loop, and renderer one at a time.

Common failures

SymptomCheckNext action
Unresolved symbols or loader failureLibrary path, architecture, target triple, matched header/binaryRebuild the library at the pinned revision and correct link/runtime search paths
PTY constructor failsShell executable, working directory, environment, platform prerequisitesRecord the status/error and try a valid shell and directory
First frame is blankDid the process output arrive? Was the first frame forced full?Feed known bytes to a display terminal to separate timing from parsing
Display-only input does nothingIs the host calling write instead of its transport?Send encoded bytes to the external process
Display-only loop spinsC display handles have no wake channelSchedule from transport delivery rather than a wake wait
Content corrupts after an incremental updateSpan ordering and inclusive right boundsApply spans sequentially into a retained full grid
Text stops repaintingDamage consumed twice, wakeups disabled, or unhandled has_moreUse one damage path and reschedule pending work
Cursor remains at its old positionEmpty cell updates discardedUpdate metadata and invalidate old/new cursor bounds
CJK characters appear twiceWide spacer cells rendered as textSkip spacer text and preserve its occupied cell
Combining text/underline variants are lostCompact cell format used for rich typographyUse rich Rust reads where those details are required
Glyph geometry appears everywhere on idleZero spans passed to the glyph plannerZero spans means full plan; skip idle planning
Colors disagree with application queriesHost colors changed without updating terminal query colorsApply the same resolved appearance to runtime and renderer
Search highlights jump or wrapSearch buffer rows treated as viewport rowsConvert using history size/display offset and refresh stale results
Remote application stalls on terminal queriesDisplay-only replies discardedDrain with a reply host/callback and forward bytes to the transport
Clipboard reads never completeRead reply deferred until after callback returnReply synchronously; handle asynchronous permission UI separately
Crash during teardownHandle freed while waiter/task still used itStop work, notify, join, cancel queued users, then free
Memory grows after each frameMissing batch free, or output variable overwrittenAudit every successful allocation and its owner
Animated image freezesNo timer after output becomes idleSchedule from nonzero next_frame_delay_ms and refresh placements

Integration smoke tests

Use deterministic parser fixtures where possible; exercise PTY behavior separately. These checks test the host's integration, not just that the library compiled.

ScenarioExpected evidence
Known ASCII plus ANSI color outputCorrect cell text and colors in the first full frame
Second output chunk modifying a small areaPatched retained grid matches a fresh full snapshot
Cursor move without ordinary textCursor redraws without stale pixels
Resize smaller and largerNew dimensions, full retained buffer, aligned hit testing
Wide and combining textNo duplicate wide glyphs; documented compact/rich text behavior
Box drawing and long/short Braille runsCorrect geometry and intentional spinner shaping
Keyboard press/repeat/releaseBytes follow the active application's negotiated mode
Bracketed paste enabled and disabledExactly one correctly delimited or plain payload
Mouse reporting enabled and disabledApplication receives reports only when appropriate
Enough output to create historyScrolling works; search finds off-screen text with correct highlights
Device/color query in a display terminalReply reaches the external process, not the parser input
Clipboard denied and supported pathsPrompt policy respected and requests always completed
Several queued event batcheshas_more is honored without starving the UI
Close while a waiter is blockedWaiter exits before handle destruction, with no late callbacks
Kitty static/animated image, if supported by hostCorrect clipping, placement, resource release, and timed redraw

For the incremental-frame check, compare dimensions, every retained cell, and cursor/scroll metadata against snapshot(). Include a scroll and a resize; comparing only the first full frame does not validate patching.

Focused repository checks

From the Termy repository root:

cargo test -p termy_core --test display_terminal
cargo test -p termy_core --test ffi_export_guard
cargo test -p termy_core
cargo build --release -p termy_core --lib

Run checks relevant to the code you changed. Website-only documentation edits can be validated with bun run types:check and bun run build from website/, plus compilation of changed examples. After an ABI change, rebuild the library before testing host examples so stale binaries cannot hide a mismatch.

Report a reproducible integration issue

Include the pinned Termy commit, OS and architecture, Rust/C API choice, PTY or display-only mode, grid/cell dimensions, and the smallest output byte sequence that reproduces the problem. For rendering bugs, describe the frame API, damage kind/spans, and expected versus actual retained cells. For FFI failures, include the function name and status code.

Remove credentials and private terminal content from reproductions. State which core tests and host checks ran; separate a parser result from a visual result and a tested platform from an assumed one.

On this page