{"record":{"id":"4fbddc0c53b6b7cc","repo":"thedotmack/claude-mem","slug":"validation-error","errorCode":null,"errorMessage":"validation.error","messagePattern":"validation\\.error","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"src/services/worker/http/routes/SettingsRoutes.ts","lineNumber":93,"sourceCode":"    app.get('/api/mcp/status', this.handleGetMcpStatus.bind(this));\n    app.post('/api/mcp/toggle', validateBody(toggleMcpSchema), this.handleToggleMcp.bind(this));\n  }\n\n  private handleGetSettings = this.wrapHandler((req: Request, res: Response): void => {\n    const settingsPath = paths.settings();\n    this.ensureSettingsFile(settingsPath);\n    const settings = SettingsDefaultsManager.loadFromFile(settingsPath);\n    res.json(redactSecretSettings(settings));\n  });\n\n  private handleGetDependencyHealth = this.wrapHandler((_req: Request, res: Response): void => {\n    res.json(snapshotDependencyHealth());\n  });\n\n  private handleUpdateSettings = this.wrapHandler((req: Request, res: Response): void => {\n    const validation = this.validateSettings(req.body);\n    if (!validation.valid) {\n      res.status(400).json({\n        success: false,\n        error: validation.error\n      });\n      return;\n    }\n\n    const settingsPath = paths.settings();\n    this.ensureSettingsFile(settingsPath);\n    let settings: any = {};\n\n    if (existsSync(settingsPath)) {\n      const settingsData = readFileSync(settingsPath, 'utf-8');\n      try {\n        settings = parseJsonWithBom(settingsData);\n      } catch (parseError) {\n        const normalizedParseError = parseError instanceof Error ? parseError : new Error(String(parseError));\n        logger.error('HTTP', 'Failed to parse settings file', { settingsPath }, normalizedParseError);\n        res.status(500).json({","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/worker/http/routes/SettingsRoutes.ts#L75-L111","documentation":"handleUpdateSettings runs the request body through this.validateSettings and, on failure, returns 400 with success:false and the specific validation error message. The 'validation.error' in the error record is the generic marker; the actual message comes from validateSettings.","triggerScenarios":"PUT/POST to the settings update route with a body containing an invalid setting key, out-of-range value, wrong type, or an unknown field rejected by validateSettings.","commonSituations":"Client UI or script writes a setting with a typo'd key; writing a number where a boolean/enum is expected; attempting to set a setting removed or renamed in a newer worker version; sending the whole settings object with stale fields.","solutions":["Read the 'error' field of the 400 response — it names the offending setting and reason","Correct the setting key/value to match the current settings schema","GET the current settings first and modify only known-valid keys","Update the client/script if the settings schema changed between versions"],"exampleFix":"// before\nawait fetch('/api/settings', { method: 'PUT', body: JSON.stringify({ autoCompact: 'yes' }) });\n// after\nawait fetch('/api/settings', { method: 'PUT', body: JSON.stringify({ autoCompact: true }) });","handlingStrategy":"validation","validationCode":"const current = await (await fetch('/api/settings')).json();\nconst next = { ...current, autoCompact: true }; // modify only known keys\n// verify keys exist before sending\nfor (const k of Object.keys(changes)) if (!(k in current)) throw new Error(`Unknown setting: ${k}`);","typeGuard":"function isSettingKey(k: string): k is keyof SettingsSnapshot {\n  return k in DEFAULT_SETTINGS;\n}","tryCatchPattern":"const res = await fetch('/api/settings', { method: 'PUT', body: JSON.stringify(changes) });\nif (res.status === 400) {\n  const body = await res.json();\n  throw new Error(`Settings rejected: ${body.error}`);\n}","preventionTips":["GET current settings and merge changes instead of posting a hand-built object","Validate setting keys/values against the schema client-side before the PUT","After version upgrades, diff your settings writes against the new schema","Surface the response's 'error' string directly to users — it names the offending field"],"tags":["http","validation","settings"],"backgroundTag":"invalid-config-value","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}