thedotmack/claude-mem · error · Error

Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing

Error message

Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing to overwrite

What it means

mergeAndWriteHooksJson() reads the Windsurf hooks.json; if it exists but JSON.parse fails, the installer refuses to overwrite the user's existing config (which may be partially valid) and throws after logging the parse error. This mirrors the same protective pattern used for Gemini/Antigravity settings.

Source

Thrown at src/services/integrations/WindsurfHooksInstaller.ts:142

  workerServicePath: string,
  workingDirectory: string,
): void {
  mkdirSync(WINDSURF_HOOKS_DIR, { recursive: true });

  let existingConfig: WindsurfHooksJson = { hooks: {} };
  if (existsSync(WINDSURF_HOOKS_JSON_PATH)) {
    try {
      existingConfig = JSON.parse(readFileSync(WINDSURF_HOOKS_JSON_PATH, 'utf-8'));
      if (!existingConfig.hooks) {
        existingConfig.hooks = {};
      }
    } catch (error) {
      if (error instanceof Error) {
        logger.error('WORKER', 'Corrupt hooks.json, refusing to overwrite', { path: WINDSURF_HOOKS_JSON_PATH }, error);
      } else {
        logger.error('WORKER', 'Corrupt hooks.json, refusing to overwrite', { path: WINDSURF_HOOKS_JSON_PATH }, new Error(String(error)));
      }
      throw new Error(`Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing to overwrite`);
    }
  }

  for (const eventName of WINDSURF_HOOK_EVENTS) {
    const command = buildHookCommand(bunPath, workerServicePath, eventName);

    const hookEntry: WindsurfHookEntry = {
      command,
      show_output: false,
      working_directory: workingDirectory,
    };

    const existingHooks = (existingConfig.hooks[eventName] ?? []).filter(
      (hook) => !hook.command.includes('worker-service') || !hook.command.includes('windsurf')
    );

    existingConfig.hooks[eventName] = [...existingHooks, hookEntry];
  }

View on GitHub (pinned to d768ba3643)

Solutions

  1. Open the Windsurf hooks.json path and fix the JSON syntax (validate with a JSON linter).
  2. If unsalvageable, back up then replace with `{ "hooks": {} }` and re-run the installer.
  3. Re-run `npx claude-mem@latest install` (Windsurf path) once the file parses.

Example fix

// before — hooks.json: { "hooks": { , } }

// after
{
  "hooks": {}
}
// then re-run the Windsurf installer step
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync, existsSync } from 'fs';

function windsurfHooksJsonValid(path: string): boolean {
  if (!existsSync(path)) return true;
  try { JSON.parse(readFileSync(path, 'utf-8')); return true; }
  catch { return false; }
}

Type guard

function isCorruptWindsurfHooksError(e: unknown): boolean {
  return e instanceof Error && /Corrupt hooks\.json .* refusing to overwrite/i.test(e.message);
}

Try / catch

try {
  mergeAndWriteHooksJson(bunPath, workerServicePath, cwd);
} catch (e) {
  if (e instanceof Error && /refusing to overwrite/i.test(e.message)) {
    console.error(`${e.message}\nFix the JSON (or back it up and replace with {"hooks":{}}), then re-run.`);
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Running installWindsurfHooks when the Windsurf hooks.json file (WINDSURF_HOOKS_JSON_PATH) is present but contains invalid JSON.

Common situations: User hand-edited the hooks.json and left a syntax error; another hook installer wrote malformed JSON and crashed; file truncated by an interrupted write; merge-conflict markers left in the file.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/10a2284a9a1c7cbe. Report an issue: GitHub.