slopus/happy · error · TmuxSessionIdentifierError
Window identifier required: ${sessionIdentifier}
Error message
Window identifier required: ${sessionIdentifier} What it means
killWindow() kills a tmux window but requires an identifier that names BOTH a session and a window (e.g. 'session:window'). parseTmuxSessionIdentifier() splits the string; if no window component is present (e.g. just a session name), this TmuxSessionIdentifierError is thrown instead of running a dangerous or ambiguous 'kill-window' tmux command.
Source
Thrown at packages/happy-cli/src/utils/tmux.ts:895
return info;
} catch (error) {
if (error instanceof TmuxSessionIdentifierError) {
logger.debug(`[TMUX] Invalid session identifier: ${error.message}`);
} else {
logger.debug('[TMUX] Error getting session info:', error);
}
return null;
}
}
/**
* Kill a tmux window safely with proper error handling
*/
async killWindow(sessionIdentifier: string): Promise<boolean> {
try {
const parsed = parseTmuxSessionIdentifier(sessionIdentifier);
if (!parsed.window) {
throw new TmuxSessionIdentifierError(`Window identifier required: ${sessionIdentifier}`);
}
const result = await this.executeWinOp('kill-window', [parsed.window], parsed.session);
return result;
} catch (error) {
if (error instanceof TmuxSessionIdentifierError) {
logger.debug(`[TMUX] Invalid window identifier: ${error.message}`);
} else {
logger.debug('[TMUX] Error killing window:', error);
}
return false;
}
}
/**
* List windows in a session
*/
async listWindows(sessionName?: string): Promise<string[]> {View on GitHub (pinned to b824cd0a46)
Solutions
- Pass a full 'session:window' identifier, e.g. killWindow('myproj:main').
- Before calling, format the identifier with formatTmuxSessionIdentifier({ session, window }).
- Log/inspect the sessionIdentifier argument at the call site to confirm the window segment exists.
- If you only know the session, list its windows (list-windows) first and pick one explicitly.
Example fix
// before
await tmux.killWindow('happy-session');
// after
await tmux.killWindow('happy-session:main'); Defensive patterns
Strategy: validation
Validate before calling
function canKillWindow(id) {
const s = String(id ?? '');
const colon = s.indexOf(':');
return colon >= 0 && s.slice(colon + 1).length > 0;
}
if (!canKillWindow(identifier)) throw new Error('killWindow needs session:window'); Type guard
function hasWindowTarget(id) {
return typeof id === 'string' && /^[^:]+:[^:]+$/.test(id);
} Try / catch
try {
await tmux.killWindow(id);
} catch (e) {
if (e instanceof TmuxSessionIdentifierError) {
console.error(`Bad window target '${id}': use session:window format`);
return false;
}
throw e;
} Prevention
- Always build identifiers with formatTmuxSessionIdentifier({ session, window }).
- Never pass a bare session name to window-scoped operations.
- Store session and window as separate fields and join at call time.
- Unit-test identifier formatting for all call sites.
When it happens
Trigger: Calling killWindow() with a bare session name like 'happy-abc123', an empty string, or a 'session:' value with an empty window part — anything parseTmuxSessionIdentifier returns without a window field.
Common situations: Passing a tmux session identifier (not a window identifier) from config or a stored session string; upstream code refactored from session-scoped to window-scoped targeting; a window name was dropped when formatting the identifier.
Related errors
- Session identifier must be a non-empty string
- Invalid session identifier: missing session name
- Invalid session name: "${result.session}". Only alphanumeric
- Invalid window name: "${result.window}". Only alphanumeric c
- Invalid pane identifier: "${result.pane}". Only numeric valu
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/0bb81d72e6c3ea34.
Report an issue: GitHub.