{"record":{"id":"538f9d48bfc76355","repo":"slopus/happy","slug":"session-identifier-must-be-a-non-empty-string","errorCode":null,"errorMessage":"Session identifier must be a non-empty string","messagePattern":"Session identifier must be a non-empty string","errorType":"exception","errorClass":"TmuxSessionIdentifierError","httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/utils/tmux.ts","lineNumber":125,"sourceCode":"// Strongly typed tmux session identifier with validation\nexport interface TmuxSessionIdentifier {\n    session: string;\n    window?: string;\n    pane?: string;\n}\n\n/** Validation error for tmux session identifiers */\nexport class TmuxSessionIdentifierError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'TmuxSessionIdentifierError';\n    }\n}\n\n// Helper to parse tmux session identifier from string with validation\nexport function parseTmuxSessionIdentifier(identifier: string): TmuxSessionIdentifier {\n    if (!identifier || typeof identifier !== 'string') {\n        throw new TmuxSessionIdentifierError('Session identifier must be a non-empty string');\n    }\n\n    // Format: session:window or session:window.pane or just session\n    const parts = identifier.split(':');\n    if (parts.length === 0 || !parts[0]) {\n        throw new TmuxSessionIdentifierError('Invalid session identifier: missing session name');\n    }\n\n    const result: TmuxSessionIdentifier = {\n        session: parts[0].trim()\n    };\n\n    // Validate session name (tmux has restrictions on session names)\n    if (!/^[a-zA-Z0-9._-]+$/.test(result.session)) {\n        throw new TmuxSessionIdentifierError(`Invalid session name: \"${result.session}\". Only alphanumeric characters, dots, hyphens, and underscores are allowed.`);\n    }\n\n    if (parts.length > 1) {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/utils/tmux.ts#L107-L143","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass a non-empty string identifier, e.g. parseTmuxSessionIdentifier('happy:0.0').","Check where the identifier comes from (config/env) and provide a default like 'happy' when empty.","Wrap in try-catch against TmuxSessionIdentifierError and fall back to a default session.","Validate the raw value with a guard before calling."],"exampleFix":"// before\nconst id = parseTmuxSessionIdentifier(config.tmuxSession); // '' -> throws\n// after\nconst id = parseTmuxSessionIdentifier(config.tmuxSession?.trim() || 'happy');","handlingStrategy":"validation","validationCode":"function isValidTmuxIdentifier(id: unknown): id is string {\n  return typeof id === 'string' && id.trim().length > 0;\n}\nif (!isValidTmuxIdentifier(raw)) throw new Error('tmux identifier required');\nparseTmuxSessionIdentifier(raw);","typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.trim().length > 0;\n}","tryCatchPattern":"try {\n  const id = parseTmuxSessionIdentifier(raw);\n} catch (err) {\n  if (err instanceof TmuxSessionIdentifierError) {\n    return parseTmuxSessionIdentifier('happy'); // default session\n  }\n  throw err;\n}","preventionTips":["Default empty config/env session names to a known value like 'happy'.","Never pipe empty lookup results straight back into the parser.","Persist identifiers only after successful parsing."],"tags":["tmux","validation","input-validation"],"backgroundTag":"invalid-tmux-session-identifier","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}