{"record":{"id":"bc6e6879953dc97e","repo":"Yeachan-Heo/oh-my-codex","slug":"sanitizeteamname-empty-after-sanitization","errorCode":null,"errorMessage":"sanitizeTeamName: empty after sanitization","messagePattern":"sanitizeTeamName: empty after sanitization","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/tmux-session.ts","lineNumber":2315,"sourceCode":"    workerCli,\n    command: platformSpec.command,\n    args: platformSpec.args,\n    env: scrubTeamWorkerHudOwnershipEnv(workerEnv),\n  };\n}\n\n// Sanitize team name: lowercase, alphanumeric + hyphens, max 30 chars\nexport function sanitizeTeamName(name: string): string {\n  const lowered = name.toLowerCase();\n  const replaced = lowered\n    .replace(/[^a-z0-9]+/g, '-')\n    .replace(/-+/g, '-')\n    .replace(/^-/, '')\n    .replace(/-$/, '');\n\n  const truncated = replaced.slice(0, 30).replace(/-$/, '');\n  if (truncated.trim() === '') {\n    throw new Error('sanitizeTeamName: empty after sanitization');\n  }\n  return truncated;\n}\n\n/**\n * Detect whether the process is running inside a WSL2 environment.\n * WSL2 always sets WSL_DISTRO_NAME; WSL_INTEROP is also present.\n * Fallback: check /proc/version for the Microsoft kernel string.\n */\nexport function isWsl2(): boolean {\n  if (process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP) {\n    return true;\n  }\n  try {\n    const version = readFileSync('/proc/version', 'utf-8');\n    return /microsoft/i.test(version);\n  } catch {\n    return false;","sourceCodeStart":2297,"sourceCodeEnd":2333,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/tmux-session.ts#L2297-L2333","documentation":"sanitizeTeamName normalizes a team name (lowercase, separators collapsed, trimmed to 30 chars) before it is embedded in tmux session/pane identifiers. If the input consists only of characters that are all stripped during sanitization (e.g. punctuation/whitespace), the result is the empty string, which cannot be used as a tmux name, so the function throws.","triggerScenarios":"Calling createTeamSession (or any API that derives a tmux session name) with a teamName like '!!!', '---', '   ', or non-ASCII characters that are all removed by the sanitizer, so truncated.trim() === ''.","commonSituations":"Passing user-supplied or CLI-provided team names containing only symbols/emoji, dynamically generated names from branch names or ticket IDs that sanitize to nothing, or passing undefined-ish placeholders like '-'.","solutions":["Use a team name containing at least one alphanumeric ASCII character, e.g. 'team-1'.","Pre-validate/sanitize the name yourself before calling the API and fall back to a default like `team` when empty.","If names come from automation, slugify upstream identifiers and guarantee a non-empty prefix."],"exampleFix":"// before\ncreateTeamSession('!!!', 3);\n// after\nconst name = sanitize('!!!') || 'team';\ncreateTeamSession(name, 3);","handlingStrategy":"validation","validationCode":"const okTeamName = (n: string) =>\n  /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/.test(n) && n.length <= 30 && n.length > 0;\nif (!okTeamName(teamName)) teamName = 'team';","typeGuard":"const isSanitizableTeamName = (n: unknown): n is string =>\n  typeof n === 'string' && /[a-z0-9]/i.test(n);","tryCatchPattern":null,"preventionTips":["Default missing/empty names to a constant like 'team'.","Slugify external identifiers before passing them as team names."],"tags":["validation","tmux","team-mode","invalid-argument"],"backgroundTag":"invalid-argument-validation","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}