{"record":{"id":"b4692abb22a098ce","repo":"can1357/oh-my-pi","slug":"invalid-alias-aliasname-refusing-to-create-a","errorCode":null,"errorMessage":"Invalid alias \"${aliasName}\". Refusing to create a ${shell} reserved word.","messagePattern":"Invalid alias \"(.+?)\"\\. Refusing to create a (.+?) reserved word\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/profile-alias.ts","lineNumber":161,"sourceCode":"\t\t\treturn POSIX_RESERVED_ALIAS_NAMES;\n\t\tcase \"fish\":\n\t\t\treturn FISH_RESERVED_ALIAS_NAMES;\n\t\tcase \"powershell\":\n\t\tcase \"pwsh\":\n\t\t\treturn POWERSHELL_RESERVED_ALIAS_NAMES;\n\t}\n}\n\nfunction validateAliasName(aliasName: string, shell: ProfileAliasShell): string {\n\tconst normalized = aliasName.trim();\n\tif (!ALIAS_NAME_RE.test(normalized)) {\n\t\tthrow new Error(`Invalid alias \"${aliasName}\". Alias names must match ${ALIAS_NAME_RE.source}.`);\n\t}\n\tif (normalized.toLowerCase() === \"omp\") {\n\t\tthrow new Error('Invalid alias \"omp\". Refusing to shadow the base omp command.');\n\t}\n\tif (getReservedAliasNames(shell).has(normalized.toLowerCase())) {\n\t\tthrow new Error(`Invalid alias \"${aliasName}\". Refusing to create a ${shell} reserved word.`);\n\t}\n\treturn normalized;\n}\n\n// On Windows the launching shell is rarely exported through $SHELL, so when it\n// is missing we infer the PowerShell edition from the inherited environment.\n// PowerShell 7 (pwsh) always seeds PSModulePath with separator-delimited\n// \".../PowerShell/...\" module directories (plus the Windows PowerShell ones for\n// back-compat), whereas Windows PowerShell 5.1 only ever lists\n// \".../WindowsPowerShell/...\". The separator anchors keep \"WindowsPowerShell\"\n// from matching. POWERSHELL_DISTRIBUTION_CHANNEL is set only by some pwsh\n// distributions, so it stays a secondary hint rather than the primary signal.\nfunction detectWindowsPowerShell(env: NodeJS.ProcessEnv): ProfileAliasShell {\n\tconst modulePath = env.PSModulePath ?? env.PSMODULEPATH ?? env.psmodulepath ?? \"\";\n\tif (/[\\\\/]PowerShell[\\\\/]/i.test(modulePath)) return \"pwsh\";\n\tif (env.POWERSHELL_DISTRIBUTION_CHANNEL) return \"pwsh\";\n\treturn \"powershell\";\n}","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/profile-alias.ts#L143-L179","documentation":"validateAliasName rejects alias names that collide with reserved words of the target shell (e.g. `if`, `else`, `function`, PowerShell cmdlet keywords). Installing such an alias would produce a shell profile that fails to parse or silently breaks shell semantics. The reserved set is shell-specific via getReservedAliasNames(shell).","triggerScenarios":"Running `omp --alias <reservedWord>` where the (lowercased) name is in getReservedAliasNames(shell) for the detected shell — e.g. `--alias for` under bash/zsh or `--alias if` under PowerShell.","commonSituations":"Choosing short convenient names like `for`, `do`, `in`, or `switch` that happen to be shell keywords; scripts generating aliases from user input without pre-checking.","solutions":["Pick a non-reserved alias name, e.g. append a suffix like `-cmd` (`--alias for-cmd`)","Verify the name against your shell's reserved words before running the command","If a script generates names, filter them against getReservedAliasNames for the target shell first"],"exampleFix":"// before\nomp --profile work --alias for\n// after\nomp --profile work --alias for-work","handlingStrategy":"validation","validationCode":"import { getReservedAliasNames } from \"./profile-alias\"; // or replicate the check\nconst name = aliasName.trim();\nif (getReservedAliasNames(\"bash\").has(name.toLowerCase())) throw new Error(`\"${aliasName}\" is a shell reserved word`);","typeGuard":"function isReservedWord(name: string, shell: string, reserved: Set<string>): boolean {\n  return reserved.has(name.trim().toLowerCase());\n}","tryCatchPattern":"try {\n  await installProfileAlias({ profile, aliasName });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('reserved word')) {\n    console.error(`Pick a name that is not a ${shell} reserved word.`);\n    return;\n  }\n  throw err;\n}","preventionTips":["Check candidate names against your shell's keyword list (bash/zsh keywords, PowerShell cmdlet/keyword names) before installing","Avoid one- and two-letter generic names that commonly collide (for, if, do, in)","When generating names programmatically, append a suffix like \"-cmd\" to guarantee non-reserved identifiers"],"tags":["cli","validation","alias","shell","reserved-word"],"backgroundTag":"reserved-name-conflict","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}