slopus/happy · error · TmuxSessionIdentifierError
Session identifier must have a session name
Error message
Session identifier must have a session name
What it means
formatTmuxSessionIdentifier converts a TmuxSessionIdentifier object back into a 'session:window.pane' string and requires the session field to be a non-empty string. If identifier.session is missing, null, or empty, it throws this TmuxSessionIdentifierError because the resulting target string would be invalid.
Source
Thrown at packages/happy-cli/src/utils/tmux.ts:165
if (result.window && !/^[a-zA-Z0-9._-]+$/.test(result.window)) {
throw new TmuxSessionIdentifierError(`Invalid window name: "${result.window}". Only alphanumeric characters, dots, hyphens, and underscores are allowed.`);
}
if (windowAndPane.length > 1) {
result.pane = windowAndPane[1]?.trim();
if (result.pane && !/^[0-9]+$/.test(result.pane)) {
throw new TmuxSessionIdentifierError(`Invalid pane identifier: "${result.pane}". Only numeric values are allowed.`);
}
}
}
return result;
}
// Helper to format tmux session identifier to string
export function formatTmuxSessionIdentifier(identifier: TmuxSessionIdentifier): string {
if (!identifier.session) {
throw new TmuxSessionIdentifierError('Session identifier must have a session name');
}
let result = identifier.session;
if (identifier.window) {
result += `:${identifier.window}`;
if (identifier.pane) {
result += `.${identifier.pane}`;
}
}
return result;
}
// Helper to extract session and window from tmux output with improved validation
export function extractSessionAndWindow(tmuxOutput: string): { session: string; window: string } | null {
if (!tmuxOutput || typeof tmuxOutput !== 'string') {
return null;
}
View on GitHub (pinned to b824cd0a46)
Solutions
- Always set session before formatting: { session: 'happy', window: '0' }.
- Apply a default when the source value is empty: session ?? 'happy'.
- Check the object with a type guard before calling format.
- Catch TmuxSessionIdentifierError and re-create the identifier from defaults.
Example fix
// before
formatTmuxSessionIdentifier({ window: '0' }); // throws
// after
formatTmuxSessionIdentifier({ session: activeSession ?? 'happy', window: '0' }); Defensive patterns
Strategy: type-guard
Validate before calling
function canFormatTmuxIdentifier(id: TmuxSessionIdentifier): boolean {
return typeof id.session === 'string' && id.session.length > 0;
}
if (!canFormatTmuxIdentifier(id)) throw new Error('session required before formatting');
formatTmuxSessionIdentifier(id); Type guard
function hasSession(id: TmuxSessionIdentifier): id is TmuxSessionIdentifier & { session: string } {
return typeof id.session === 'string' && id.session.length > 0;
} Try / catch
try {
return formatTmuxSessionIdentifier(id);
} catch (err) {
if (err instanceof TmuxSessionIdentifierError) {
return formatTmuxSessionIdentifier({ ...id, session: id.session || 'happy' });
}
throw err;
} Prevention
- Type identifiers as TmuxSessionIdentifier with a required session field, not loose objects.
- Apply defaults (session ?? 'happy') at construction time.
- Validate serialized identifiers on load before re-formatting.
When it happens
Trigger: Calling formatTmuxSessionIdentifier({} ), { session: '' }, { window: '0' } — building the object dynamically where the session field was never assigned, or spreading a partial object returned by an earlier failed parse.
Common situations: Constructing the identifier from optional config fields where session defaulted to undefined; persisting/restoring a serialized identifier that lost its session key; programmatically building targets from list output that lacked a session name.
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/ea3d39530b608abc.
Report an issue: GitHub.