slopus/happy · error

Failed to create tmux window: ${createResult?.stderr}

Error message

Failed to create tmux window: ${createResult?.stderr}

What it means

spawnInTmux creates the target window with `tmux new-window ... -F '#{pane_pid}'` to immediately capture the spawned process's PID. If executeTmuxCommand returns null or a non-zero returncode, it throws this Error embedding tmux's stderr, meaning the window (and thus the command) could not be created.

Source

Thrown at packages/happy-cli/src/utils/tmux.ts:839

                        .replace(/`/g, '\\`');    // Backticks

                    createWindowArgs.push('-e', `${key}="${escapedValue}"`);
                }
                logger.debug(`[TMUX] Setting ${Object.keys(env).length} environment variables in tmux window`);
            }

            // Add the command to run in the window (runs immediately when window is created)
            createWindowArgs.push(fullCommand);

            // Add -P flag to print the pane PID immediately
            createWindowArgs.push('-P');
            createWindowArgs.push('-F', '#{pane_pid}');

            // Create window with command and get PID immediately
            const createResult = await this.executeTmuxCommand(createWindowArgs, sessionName);

            if (!createResult || createResult.returncode !== 0) {
                throw new Error(`Failed to create tmux window: ${createResult?.stderr}`);
            }

            // Extract the PID from the output
            const panePid = parseInt(createResult.stdout.trim());
            if (isNaN(panePid)) {
                throw new Error(`Failed to extract PID from tmux output: ${createResult.stdout}`);
            }

            logger.debug(`[TMUX] Spawned command in tmux session ${sessionName}, window ${windowName}, PID ${panePid}`);

            // Return tmux session info and PID
            const sessionIdentifier: TmuxSessionIdentifier = {
                session: sessionName,
                window: windowName
            };

            return {
                success: true,

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Read the stderr embedded in the message — it contains tmux's own failure reason.
  2. Ensure the session exists first (tmux new-session -d) or pass a session name spawnInTmux can create.
  3. Check the command string is a valid shell command and properly quoted.
  4. Retry: this is often transient (server restart, race with session termination).
  5. Verify tmux works manually: tmux new-window -t happy -F '#{pane_pid}' 'echo hi'.

Example fix

// before
await tmux.spawnInTmux(cmd, 'gone-session'); // may throw create-window failure
// after
if (!tmux.hasSession('gone-session')) await tmux.createTmuxSession('gone-session');
await tmux.spawnInTmux(cmd, 'gone-session');
Defensive patterns

Strategy: retry

Validate before calling

// ensure the target session exists before spawning a window in it
const sessions = await execFileP('tmux', ['list-sessions', '-F', '#{session_name}']).catch(() => '');
if (!sessions.split('\n').includes(sessionName)) {
  await execFileP('tmux', ['new-session', '-d', '-s', sessionName]);
}

Try / catch

try {
  await tmux.spawnInTmux(cmd, sessionName);
} catch (err) {
  if ((err as Error).message.startsWith('Failed to create tmux window')) {
    logger.error('tmux stderr:', (err as Error).message);
    await recreateSession(sessionName); // then retry once
    await tmux.spawnInTmux(cmd, sessionName);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling spawnInTmux when the tmux new-window invocation fails: session doesn't exist and wasn't created, invalid window/command arguments, tmux server errors ('no server running', 'create window failed'), or duplicate window name without -a.

Common situations: Target tmux session killed between availability check and window creation; shell command string with quoting issues; tmux version differences in flag support; server socket permission problems; hitting tmux limits on windows per session.

Related errors


AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31). Data as JSON: /api/errors/8602b786ba22869c. Report an issue: GitHub.