slopus/happy · critical

tmux not available

Error message

tmux not available

What it means

spawnInTmux first runs `tmux list-sessions` to confirm the tmux binary is installed and usable. If executeTmuxCommand fails (returns falsy — binary missing, not executable, or the command errored), it throws 'tmux not available'. The library requires a working tmux to run commands inside sessions.

Source

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

     * - Tmux windows inherit environment from the tmux server
     * - Only NEW or DIFFERENT variables need to be set via -e flag
     * - Passing all of process.env would create 50+ unnecessary -e flags
     *
     * @param args - Command and arguments to execute (as array, will be joined)
     * @param options - Spawn options (tmux-specific, excludes env)
     * @param env - Environment variables to set in window (only pass what's different!)
     * @returns Result with success status and session identifier
     */
    async spawnInTmux(
        args: string[],
        options: TmuxSpawnOptions = {},
        env?: Record<string, string>
    ): Promise<{ success: boolean; sessionId?: string; pid?: number; error?: string }> {
        try {
            // Check if tmux is available
            const tmuxCheck = await this.executeTmuxCommand(['list-sessions']);
            if (!tmuxCheck) {
                throw new Error('tmux not available');
            }

            // Handle session name resolution
            // - undefined: Use first existing session or create "happy"
            // - empty string: Use first existing session or create "happy"
            // - specific name: Use that session (create if doesn't exist)
            let sessionName = options.sessionName !== undefined && options.sessionName !== ''
                ? options.sessionName
                : null;

            // If no specific session name, try to use first existing session
            if (!sessionName) {
                const listResult = await this.executeTmuxCommand(['list-sessions', '-F', '#{session_name}']);
                if (listResult && listResult.returncode === 0 && listResult.stdout.trim()) {
                    // Use first session from list
                    const firstSession = listResult.stdout.trim().split('\n')[0];
                    sessionName = firstSession;
                    logger.debug(`[TMUX] Using first existing session: ${sessionName}`);

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Install tmux (apt/brew install tmux) and verify with `tmux -V`.
  2. Ensure tmux is on PATH for the process running happy (echo $PATH; which tmux).
  3. Run in an environment that supports tmux (Linux/WSL/macOS), not native Windows.
  4. Fall back to non-tmux spawn if tmux is optional for your workflow.
  5. If tmux exists but list-sessions fails, start a server or check TMUX-related permissions.

Example fix

// before
await tmux.spawnInTmux('npm test'); // Error: tmux not available
// after
if (!await isTmuxInstalled()) {
  await spawnDirectly('npm test'); // fallback
} else {
  await tmux.spawnInTmux('npm test');
}
Defensive patterns

Strategy: fallback

Validate before calling

import { execFile } from 'child_process';
import { promisify } from 'util';
const run = promisify(execFile);
async function isTmuxInstalled(): Promise<boolean> {
  try { await run('tmux', ['-V']); return true; } catch { return false; }
}

Try / catch

try {
  await tmux.spawnInTmux(cmd);
} catch (err) {
  if ((err as Error).message === 'tmux not available') {
    logger.warn('tmux missing; falling back to direct spawn');
    await spawnDirect(cmd);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling spawnInTmux on a machine where tmux is not installed, not on PATH, lacks execute permission, or where list-sessions fails for environmental reasons (e.g. no server yet combined with a broken tmux binary).

Common situations: Fresh CI containers or minimal Docker images without tmux; macOS without Homebrew tmux installed; Windows (no native tmux); PATH stripped in non-interactive shells/daemons so tmux isn't found; WSL without tmux set up.

Related errors


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