{"record":{"id":"22aa6106d98f2a82","repo":"thedotmack/claude-mem","slug":"invalid-mode-id-modeid","errorCode":null,"errorMessage":"Invalid mode ID: ${modeId}","messagePattern":"Invalid mode ID: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/domain/ModeManager.ts","lineNumber":87,"sourceCode":"    const result = { ...base } as T;\n\n    for (const key in override) {\n      const overrideValue = override[key];\n      const baseValue = base[key];\n\n      if (this.isPlainObject(overrideValue) && this.isPlainObject(baseValue)) {\n        result[key] = this.deepMerge(baseValue, overrideValue as any);\n      } else {\n        result[key] = overrideValue as T[Extract<keyof T, string>];\n      }\n    }\n\n    return result;\n  }\n\n  private loadModeFile(modeId: string): ModeConfig {\n    if (!MODE_ID_PATTERN.test(modeId)) {\n      throw new Error(`Invalid mode ID: ${modeId}`);\n    }\n\n    const modePath = this.modeDirs\n      .map(modesDir => join(modesDir, `${modeId}.json`))\n      .find(candidate => existsSync(candidate));\n\n    if (!modePath) {\n      throw new Error(`Mode file not found: ${modeId}.json (searched: ${this.modeDirs.join(', ')})`);\n    }\n\n    const jsonContent = readFileSync(modePath, 'utf-8');\n    return JSON.parse(jsonContent) as ModeConfig;\n  }\n\n  loadMode(modeId: string): ModeConfig {\n    const inheritance = this.parseInheritance(modeId);\n\n    if (!inheritance.hasParent) {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/domain/ModeManager.ts#L69-L105","documentation":"Thrown by ModeManager.loadModeFile() when the mode id fails the MODE_ID_PATTERN regex (/^[a-z0-9]+(?:-[a-z0-9]+)*(?:--[a-z0-9]+(?:-[a-z0-9]+)*)?$/). This rejects uppercase, special characters, leading/trailing dashes, or any character outside lowercase alphanumeric and single-hyphen segments.","triggerScenarios":"Passing a mode id with uppercase ('Code'), spaces, underscores, slashes, or other punctuation to loadMode()/loadModeFile(). Also a mode id that starts or ends with a dash.","commonSituations":"User names a custom mode 'Code-Review' (uppercase) or 'code_review' (underscore); a path-style id 'modes/code'; copy-paste introduced a trailing space or dash.","solutions":["Rename the mode id to lowercase alphanumeric with single hyphens only, e.g. 'code-review'.","Rename the corresponding .json file to match, since loadModeFile looks up <modeId>.json.","If you need an override, use the double-hyphen form 'parent--override' (both segments still lowercase-alphanumeric-hyphen)."],"exampleFix":"// before\nmanager.loadMode('Code_Review');\n// throws 'Invalid mode ID: Code_Review'\n\n// after — rename file to modes/code-review.json and call\nmanager.loadMode('code-review');","handlingStrategy":"validation","validationCode":"const MODE_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*(?:--[a-z0-9]+(?:-[a-z0-9]+)*)?$/;\nif (!MODE_ID_PATTERN.test(modeId)) {\n  throw new Error(`Rejecting invalid mode id early: ${modeId}`);\n}","typeGuard":"function isValidModeId(modeId: string): boolean {\n  return /^[a-z0-9]+(?:-[a-z0-9]+)*(?:--[a-z0-9]+(?:-[a-z0-9]+)*)?$/.test(modeId);\n}","tryCatchPattern":null,"preventionTips":["Name modes with lowercase alphanumeric and single hyphens only.","Rename the .json file to match the normalized id exactly.","Reject uppercase, underscores, and slashes at the authoring UI before they reach ModeManager."],"tags":["modes","validation","config"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}