{"record":{"id":"10a2284a9a1c7cbe","repo":"thedotmack/claude-mem","slug":"corrupt-hooks-json-at-windsurf-hooks-json-path","errorCode":null,"errorMessage":"Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing to overwrite","messagePattern":"Corrupt hooks\\.json at (.+?), refusing to overwrite","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/integrations/WindsurfHooksInstaller.ts","lineNumber":143,"sourceCode":"  workerServicePath: string,\n  workingDirectory: string,\n): void {\n  mkdirSync(WINDSURF_HOOKS_DIR, { recursive: true });\n\n  let existingConfig: WindsurfHooksJson = { hooks: {} };\n  if (existsSync(WINDSURF_HOOKS_JSON_PATH)) {\n    try {\n      existingConfig = parseJsonWithBom<WindsurfHooksJson>(readFileSync(WINDSURF_HOOKS_JSON_PATH, 'utf-8'));\n      if (!existingConfig.hooks) {\n        existingConfig.hooks = {};\n      }\n    } catch (error) {\n      if (error instanceof Error) {\n        logger.error('WORKER', 'Corrupt hooks.json, refusing to overwrite', { path: WINDSURF_HOOKS_JSON_PATH }, error);\n      } else {\n        logger.error('WORKER', 'Corrupt hooks.json, refusing to overwrite', { path: WINDSURF_HOOKS_JSON_PATH }, new Error(String(error)));\n      }\n      throw new Error(`Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing to overwrite`);\n    }\n  }\n\n  for (const eventName of WINDSURF_HOOK_EVENTS) {\n    const command = buildHookCommand(bunPath, workerServicePath, eventName);\n\n    const hookEntry: WindsurfHookEntry = {\n      command,\n      show_output: false,\n      working_directory: workingDirectory,\n    };\n\n    const existingHooks = (existingConfig.hooks[eventName] ?? []).filter(\n      (hook) => !hook.command.includes('worker-service') || !hook.command.includes('windsurf')\n    );\n\n    existingConfig.hooks[eventName] = [...existingHooks, hookEntry];\n  }","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/integrations/WindsurfHooksInstaller.ts#L125-L161","documentation":"mergeAndWriteHooksJson reads the existing Windsurf hooks.json and merges new hook entries into it. If the file exists but cannot be parsed as JSON (corrupt), it logs and throws this error instead of overwriting the user's file, protecting unknown/ manual hook configuration from data loss.","triggerScenarios":"writeWindsurfHooksAndSetupContext invokes mergeAndWriteHooksJson while ~/.codeium/windsurf/hooks.json (WINDSURF_HOOKS_JSON_PATH) exists but contains invalid JSON — truncated write, merge-conflict markers, trailing commas, or hand-edited syntax errors.","commonSituations":"A previous crash or power loss left a partially written hooks.json; the user edited the file manually and broke the syntax; a version upgrade changed the format.","solutions":["Open WINDSURF_HOOKS_JSON_PATH and fix the JSON syntax (or delete/rename the file so the installer can recreate it).","Validate the file with a JSON linter or `bun -e 'JSON.parse(require(\"fs\").readFileSync(path))'` to find the syntax error.","Back up the file, delete it, re-run the Windsurf hooks setup, then re-apply custom hooks manually.","Re-run installation after fixing — mergeAndWriteHooksJson only proceeds when the existing file parses."],"exampleFix":"// before (hooks.json, corrupt)\n{ \"hooks\": { \"on_workspace_start\": , }\n// after\n{ \"hooks\": { \"on_workspace_start\": [] } }","handlingStrategy":"try-catch","validationCode":"const fs = require('fs');\nif (fs.existsSync(hooksPath)) {\n  try { JSON.parse(fs.readFileSync(hooksPath, 'utf8')); } catch (e) { /* fix or move the file first */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await installer.writeWindsurfHooksAndSetupContext(bunPath);\n} catch (err) {\n  if (String(err).includes('Corrupt hooks.json')) {\n    // prompt user to fix or back up hooks.json, then retry\n  }\n}","preventionTips":["Validate hooks.json after every manual edit with a JSON linter.","Keep a backup of hooks.json before edits.","Avoid interrupting the installer mid-write (atomic writes handle this, but power loss can still corrupt)."],"tags":["json","file","installer"],"backgroundTag":"json-parse-error","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"}