slopus/happy · error · TmuxSessionIdentifierError

Invalid pane identifier: "${result.pane}". Only numeric valu

Error message

Invalid pane identifier: "${result.pane}". Only numeric values are allowed.

What it means

If the identifier specifies a pane ('session:window.pane'), parseTmuxSessionIdentifier requires the pane segment to match /^[0-9]+$/ and throws this TmuxSessionIdentifierError otherwise, since tmux pane indices are numeric.

Source

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

    };

    // 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) {
        const windowAndPane = parts[1].split('.');
        result.window = windowAndPane[0]?.trim();

        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}`;

View on GitHub (pinned to b824cd0a46)

Solutions

  1. Use the numeric pane index: 'happy:0.1' not 'happy:0.%1'.
  2. Omit the pane segment and target the window only: 'happy:0'.
  3. Look up the correct index with tmux list-panes -a.
  4. Strip non-numeric suffixes from the pane token before parsing.

Example fix

// before
parseTmuxSessionIdentifier('happy:0.%3'); // throws
// after
parseTmuxSessionIdentifier('happy:0.3');
Defensive patterns

Strategy: validation

Validate before calling

const pane = identifier.split(':')[1]?.split('.')[1];
if (pane !== undefined && !/^\d+$/.test(pane)) {
  throw new Error(`Pane '${pane}' must be a numeric index, not '%N'`);
}
parseTmuxSessionIdentifier(identifier);

Type guard

function isNumericPane(pane: string | undefined): boolean {
  return pane === undefined || /^\d+$/.test(pane);
}

Try / catch

try {
  return parseTmuxSessionIdentifier(identifier);
} catch (err) {
  if (err instanceof TmuxSessionIdentifierError && /pane identifier/.test(err.message)) {
    return parseTmuxSessionIdentifier(identifier.split('.').slice(0, 2).join('.'));
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling parseTmuxSessionIdentifier with a non-numeric pane like 'happy:0.main', 'happy:0.%3', or 'happy:0.0.extra' where the extra segment yields a non-numeric pane token.

Common situations: Confusing tmux pane IDs (%N) with pane indices; passing a pane title instead of the index; copying a target string that includes extra dot-separated fields.

Related errors


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