slopus/happy · error · TmuxSessionIdentifierError

Session identifier must be a non-empty string

Error message

Session identifier must be a non-empty string

What it means

parseTmuxSessionIdentifier validates the 'session:window.pane' identifier string before parsing. It throws this TmuxSessionIdentifierError when the input is undefined/empty or not a string, since tmux commands require at least a session name. It fails fast so callers never pass a garbage identifier to the tmux CLI.

Source

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

// Strongly typed tmux session identifier with validation
export interface TmuxSessionIdentifier {
    session: string;
    window?: string;
    pane?: string;
}

/** Validation error for tmux session identifiers */
export class TmuxSessionIdentifierError extends Error {
    constructor(message: string) {
        super(message);
        this.name = 'TmuxSessionIdentifierError';
    }
}

// Helper to parse tmux session identifier from string with validation
export function parseTmuxSessionIdentifier(identifier: string): TmuxSessionIdentifier {
    if (!identifier || typeof identifier !== 'string') {
        throw new TmuxSessionIdentifierError('Session identifier must be a non-empty string');
    }

    // Format: session:window or session:window.pane or just session
    const parts = identifier.split(':');
    if (parts.length === 0 || !parts[0]) {
        throw new TmuxSessionIdentifierError('Invalid session identifier: missing session name');
    }

    const result: TmuxSessionIdentifier = {
        session: parts[0].trim()
    };

    // Validate session name (tmux has restrictions on session names)
    if (!/^[a-zA-Z0-9._-]+$/.test(result.session)) {
        throw new TmuxSessionIdentifierError(`Invalid session name: "${result.session}". Only alphanumeric characters, dots, hyphens, and underscores are allowed.`);
    }

    if (parts.length > 1) {

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Pass a non-empty string identifier, e.g. parseTmuxSessionIdentifier('happy:0.0').
  2. Check where the identifier comes from (config/env) and provide a default like 'happy' when empty.
  3. Wrap in try-catch against TmuxSessionIdentifierError and fall back to a default session.
  4. Validate the raw value with a guard before calling.

Example fix

// before
const id = parseTmuxSessionIdentifier(config.tmuxSession); // '' -> throws
// after
const id = parseTmuxSessionIdentifier(config.tmuxSession?.trim() || 'happy');
Defensive patterns

Strategy: validation

Validate before calling

function isValidTmuxIdentifier(id: unknown): id is string {
  return typeof id === 'string' && id.trim().length > 0;
}
if (!isValidTmuxIdentifier(raw)) throw new Error('tmux identifier required');
parseTmuxSessionIdentifier(raw);

Type guard

function isNonEmptyString(v: unknown): v is string {
  return typeof v === 'string' && v.trim().length > 0;
}

Try / catch

try {
  const id = parseTmuxSessionIdentifier(raw);
} catch (err) {
  if (err instanceof TmuxSessionIdentifierError) {
    return parseTmuxSessionIdentifier('happy'); // default session
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling parseTmuxSessionIdentifier(''), parseTmuxSessionIdentifier(null as any), or with an undefined variable — e.g. a session name read from empty config, an unset env var, or an empty tmux list-session field.

Common situations: Configuration file with an empty session name; environment variable like HAPPY_TMUX_SESSION unset; storing the result of a failed tmux lookup (empty string) and re-parsing it; a persisted identifier that was corrupted/truncated.

Related errors


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