slopus/happy · error
Tmux window created but no PID returned
Error message
Tmux window created but no PID returned
What it means
spawnSession launches a session inside a tmux window using tmux -P (print) to capture the spawned process's PID. If tmux reports success but no PID came back, the daemon cannot track the session, so it throws rather than creating an untracked session.
Source
Thrown at packages/happy-cli/src/daemon/run.ts:469
// Add all safe daemon environment variables (filtering out undefined)
for (const [key, value] of Object.entries(buildSessionChildEnvironment(ambientEnvironment, extraEnv))) {
if (value !== undefined) {
tmuxEnv[key] = value;
}
}
const tmuxResult = await tmux.spawnInTmux([sanitizedTmuxCommand], {
sessionName: tmuxSessionName,
windowName: windowName,
cwd: directory
}, tmuxEnv); // Pass complete environment for tmux session
if (tmuxResult.success) {
logger.debug(`[DAEMON RUN] Successfully spawned in tmux session: ${tmuxResult.sessionId}, PID: ${tmuxResult.pid}`);
// Validate we got a PID from tmux
if (!tmuxResult.pid) {
throw new Error('Tmux window created but no PID returned');
}
// Create a tracked session for tmux windows - now we have the real PID!
const trackedSession: TrackedSession = {
startedBy: 'daemon',
pid: tmuxResult.pid, // Real PID from tmux -P flag
tmuxSessionId: tmuxResult.sessionId,
directoryCreated,
message: directoryCreated
? `The path '${directory}' did not exist. We created a new folder and spawned a new session in tmux session '${tmuxSessionName}'. Use 'tmux attach -t ${tmuxSessionName}' to view the session.`
: `Spawned new session in tmux session '${tmuxSessionName}'. Use 'tmux attach -t ${tmuxSessionName}' to view the session.`
};
// Add to tracking map so webhook can find it later
pidToTrackedSession.set(tmuxResult.pid, trackedSession);
// Wait for webhook to populate session with happySessionId (exact same as regular flow)
logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${tmuxResult.pid} (tmux)`);View on GitHub (pinned to b824cd0a46)
Solutions
- Upgrade tmux to a recent version (≥3.x) so -P returns the pane PID
- Run the spawn command manually in tmux to inspect raw -P output
- Clear custom tmux configs that change output formats and retry
- Restart the daemon and retry spawning the session
Example fix
// before
if (!tmuxResult.pid) {
throw new Error('Tmux window created but no PID returned');
}
// after
if (!tmuxResult.pid) {
logger.warn('tmux returned no PID; falling back to pgrep lookup');
tmuxResult.pid = findPidBySessionId(tmuxResult.sessionId);
}
if (!tmuxResult.pid) {
throw new Error('Tmux window created but no PID returned');
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before spawning, verify tmux supports -P PID output
class CheckTmux {
static async version() {
const out = spawn.sync('tmux', ['-V']).stdout?.toString() || '';
return out; // expect tmux 3.x
}
} Try / catch
try {
const session = await spawnSession(opts);
} catch (err) {
if (err.message === 'Tmux window created but no PID returned') {
console.error('Upgrade tmux (>=3.x) or clear custom tmux output-format configs, then retry.');
} else throw err;
} Prevention
- Keep tmux at a recent version (3.x+) so -P prints pane PIDs
- Avoid tmux configs that alter -P / format output
- Kill stale tmux servers (`tmux kill-server`) after failed spawns
- Verify the session was spawned with `tmux list-windows` when in doubt
When it happens
Trigger: tmuxResult.success is true but tmuxResult.pid is falsy — the tmux -P output was empty or unparsed, e.g. an older tmux version or unexpected output format.
Common situations: tmux installed via an old version that doesn't print the pane PID as expected; tmux config (hooks, alternate formats) alters -P output; session spawning inside a wrapper that swallows tmux output.
Related errors
- Process did not die within timeout
- tmux not available
- Failed to create tmux window: ${createResult?.stderr}
- Failed to extract PID from tmux output: ${createResult.stdou
- Daemon-spawned sessions cannot use local/interactive mode. U
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/583cd5e5b632d945.
Report an issue: GitHub.