{"record":{"id":"2f140f89c4802349","repo":"slopus/happy","slug":"tmux-not-available","errorCode":null,"errorMessage":"tmux not available","messagePattern":"tmux not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/happy-cli/src/utils/tmux.ts","lineNumber":754,"sourceCode":"     * - Tmux windows inherit environment from the tmux server\n     * - Only NEW or DIFFERENT variables need to be set via -e flag\n     * - Passing all of process.env would create 50+ unnecessary -e flags\n     *\n     * @param args - Command and arguments to execute (as array, will be joined)\n     * @param options - Spawn options (tmux-specific, excludes env)\n     * @param env - Environment variables to set in window (only pass what's different!)\n     * @returns Result with success status and session identifier\n     */\n    async spawnInTmux(\n        args: string[],\n        options: TmuxSpawnOptions = {},\n        env?: Record<string, string>\n    ): Promise<{ success: boolean; sessionId?: string; pid?: number; error?: string }> {\n        try {\n            // Check if tmux is available\n            const tmuxCheck = await this.executeTmuxCommand(['list-sessions']);\n            if (!tmuxCheck) {\n                throw new Error('tmux not available');\n            }\n\n            // Handle session name resolution\n            // - undefined: Use first existing session or create \"happy\"\n            // - empty string: Use first existing session or create \"happy\"\n            // - specific name: Use that session (create if doesn't exist)\n            let sessionName = options.sessionName !== undefined && options.sessionName !== ''\n                ? options.sessionName\n                : null;\n\n            // If no specific session name, try to use first existing session\n            if (!sessionName) {\n                const listResult = await this.executeTmuxCommand(['list-sessions', '-F', '#{session_name}']);\n                if (listResult && listResult.returncode === 0 && listResult.stdout.trim()) {\n                    // Use first session from list\n                    const firstSession = listResult.stdout.trim().split('\\n')[0];\n                    sessionName = firstSession;\n                    logger.debug(`[TMUX] Using first existing session: ${sessionName}`);","sourceCodeStart":736,"sourceCodeEnd":772,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/utils/tmux.ts#L736-L772","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Install tmux (apt/brew install tmux) and verify with `tmux -V`.","Ensure tmux is on PATH for the process running happy (echo $PATH; which tmux).","Run in an environment that supports tmux (Linux/WSL/macOS), not native Windows.","Fall back to non-tmux spawn if tmux is optional for your workflow.","If tmux exists but list-sessions fails, start a server or check TMUX-related permissions."],"exampleFix":"// before\nawait tmux.spawnInTmux('npm test'); // Error: tmux not available\n// after\nif (!await isTmuxInstalled()) {\n  await spawnDirectly('npm test'); // fallback\n} else {\n  await tmux.spawnInTmux('npm test');\n}","handlingStrategy":"fallback","validationCode":"import { execFile } from 'child_process';\nimport { promisify } from 'util';\nconst run = promisify(execFile);\nasync function isTmuxInstalled(): Promise<boolean> {\n  try { await run('tmux', ['-V']); return true; } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await tmux.spawnInTmux(cmd);\n} catch (err) {\n  if ((err as Error).message === 'tmux not available') {\n    logger.warn('tmux missing; falling back to direct spawn');\n    await spawnDirect(cmd);\n  } else throw err;\n}","preventionTips":["Install tmux in your dev container/CI image (apt-get install -y tmux).","Document tmux as a prerequisite of the tooling.","Check PATH in daemons/non-interactive shells where tmux may be missing.","On Windows, use WSL rather than native Windows."],"tags":["tmux","environment","dependency-missing","process"],"backgroundTag":"dependency-not-installed","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}