zellij-org/zellij · error

failed to spawn forward-timeout driver thread

Error message

failed to spawn forward-timeout driver thread

What it means

Error "failed to spawn forward-timeout driver thread" thrown in zellij-org/zellij.

Solutions

  1. Check system resource limits (open files, processes) and the OS error attached to the failure.
  2. Retry the operation; if persistent, report the OS error with a zellij issue.

When it happens

Trigger: Occurs at zellij-client/src/stdin_ansi_parser.rs:914 when the operation fails: "failed to spawn forward-timeout driver thread". Currently there is no defensive handling preventing or contextualizing this failure before it surfaces.

Common situations: Typically resource exhaustion, invalid fd state, or platform-specific pty limitations.

Understand the failure class


AI-assisted analysis of zellij-org/zellij@e839bfffa5 (2026-08-19). Data as JSON: /api/errors/bb9acc460c38b14c. Report an issue: GitHub.

Appendix: source

Thrown at zellij-client/src/stdin_ansi_parser.rs:923

static FORWARD_TIMEOUT_RUNTIME: OnceLock<Arc<tokio::runtime::Runtime>> = OnceLock::new();

pub fn forward_timeout_runtime() -> &'static Arc<tokio::runtime::Runtime> {
    FORWARD_TIMEOUT_RUNTIME.get_or_init(|| {
        let rt = tokio::runtime::Builder::new_current_thread()
            .enable_time()
            .build()
            .expect("failed to build forward-timeout runtime");
        let rt = Arc::new(rt);
        let rt_for_driver = rt.clone();
        // `block_on(pending())` keeps the executor loop alive forever
        // on this thread; spawned timer tasks are polled as they
        // become ready (on spawn, on wake from the time driver).
        std::thread::Builder::new()
            .name("zellij-client-forward-timeout".into())
            .spawn(move || {
                rt_for_driver.block_on(std::future::pending::<()>());
            })
            .expect("failed to spawn forward-timeout driver thread");
        rt
    })
}

/// Spawn a timer task that closes a forward slot after `deadline` and
/// invokes `on_timeout(token, reply_bytes)` with whatever the slot
/// accumulated. Token-guard idempotent: if the barrier (or a
/// replacement forward) has already cleared the slot by the time the
/// timer wakes, `close_forward_on_timeout(token)` returns `None` and
/// `on_timeout` is never called — no explicit cancellation path
/// required.
///
/// Extracted as a free function so tests can drive it against a
/// `tokio::time::pause()`-backed paused runtime without instantiating
/// the full client.
pub fn schedule_forward_timeout<F>(
    runtime: &tokio::runtime::Handle,
    parser: Arc<Mutex<StdinAnsiParser>>,

View on GitHub (pinned to e839bfffa5)