{"record":{"id":"7894f888e8c6300e","repo":"jackwener/OpenCLI","slug":"failed-to-parse-settings-json-e-message","errorCode":null,"errorMessage":"Failed to parse settings.json: ${e.message}","messagePattern":"Failed to parse settings\\.json: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/antigravity/storage.js","lineNumber":358,"sourceCode":"    strategy: Strategy.LOCAL,\n    browser: false,\n    args: [],\n    columns: STORAGE_COLUMNS,\n    func: async () => {\n        if (!fs.existsSync(AG_SETTINGS_JSON)) {\n            throw new CommandExecutionError(`settings.json not found: ${AG_SETTINGS_JSON}`, '');\n        }\n        const raw = fs.readFileSync(AG_SETTINGS_JSON, 'utf-8');\n        // VSCode allows JSONC (line + block comments + trailing commas).\n        // Strip comments and trailing commas before parsing.\n        const stripped = raw\n            .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')              // block comments\n            .replace(/^\\s*\\/\\/.*$/gm, '')                  // line comments (full line)\n            .replace(/([^:\"])\\/\\/.*$/gm, '$1')             // line comments (after code)\n            .replace(/,(\\s*[}\\]])/g, '$1');                // trailing commas\n        let obj;\n        try { obj = JSON.parse(stripped); } catch (e) {\n            throw new CommandExecutionError(`Failed to parse settings.json: ${e.message}`, '');\n        }\n        const rows = [];\n        for (const [k, v] of Object.entries(obj)) {\n            rows.push({ Field: k, Value: typeof v === 'object' ? JSON.stringify(v) : String(v) });\n        }\n        return rows;\n    },\n});\n","sourceCodeStart":340,"sourceCodeEnd":367,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/antigravity/storage.js#L340-L367","documentation":"Error \"Failed to parse settings.json: ${e.message}\" thrown in jackwener/OpenCLI.","triggerScenarios":"Thrown at clis/antigravity/storage.js:358 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Open settings.json and fix or remove the invalid JSON (trailing commas, comments, unquoted keys)","Restore settings.json from a backup or delete it to regenerate defaults","Validate with a JSON linter before saving"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import * as fs from 'node:fs';\nconst raw = fs.readFileSync(settingsPath, 'utf-8');\nconst stripped = raw\n  .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n  .replace(/^\\s*\\/\\/.*$/gm, '')\n  .replace(/([^:\"])\\/\\/.*$/gm, '$1')\n  .replace(/,(\\s*[}\\]])/g, '$1');\ntry { JSON.parse(stripped); } catch (e) {\n  console.error(`settings.json will not parse even after JSONC stripping: ${e.message}`);\n}","typeGuard":"function isParsableJsonc(text) {\n  try {\n    const stripped = text.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n      .replace(/^\\s*\\/\\/.*$/gm, '')\n      .replace(/([^:\"])\\/\\/.*$/gm, '$1')\n      .replace(/,(\\s*[}\\]])/g, '$1');\n    JSON.parse(stripped);\n    return true;\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  await cli.run(['antigravity', 'settings-read']);\n} catch (e) {\n  if (String(e.message).startsWith('Failed to parse settings.json')) {\n    console.error(`Malformed settings.json: ${e.message}. Fix syntax at the reported position.`);\n  } else throw e;\n}","preventionTips":["Validate settings.json with a JSONC-aware linter after hand-editing","Beware the regex stripper can mangle URLs in values (// inside strings) — keep URL settings on lines where ([^:\"])// won't match, or verify output","Keep a backup of settings.json before bulk edits"],"tags":[],"backgroundTag":null,"analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}