{"record":{"id":"f7ab1ed97beef9d3","repo":"jackwener/OpenCLI","slug":"failed-to-parse-fixture-p-err-instanceof-err","errorCode":null,"errorMessage":"Failed to parse fixture ${p}: ${err instanceof Error ? err.message : String(err)}","messagePattern":"Failed to parse fixture (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/browser/verify-fixture.ts","lineNumber":122,"sourceCode":"  /^hn_id$/i,\n  /^username$/i,\n  /^handle$/i,\n  /^uri$/i,\n];\n\nexport function fixturePath(site: string, command: string): string {\n  return path.join(os.homedir(), '.opencli', 'sites', site, 'verify', `${command}.json`);\n}\n\nexport function loadFixture(site: string, command: string): Fixture | null {\n  const p = fixturePath(site, command);\n  if (!fs.existsSync(p)) return null;\n  try {\n    const raw = fs.readFileSync(p, 'utf-8');\n    const parsed = JSON.parse(raw) as Fixture;\n    return parsed;\n  } catch (err) {\n    throw new Error(`Failed to parse fixture ${p}: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nexport function writeFixture(site: string, command: string, fixture: Fixture): string {\n  const p = fixturePath(site, command);\n  fs.mkdirSync(path.dirname(p), { recursive: true });\n  fs.writeFileSync(p, `${JSON.stringify(fixture, null, 2)}\\n`, 'utf-8');\n  return p;\n}\n\n/**\n * Derive a reasonable fixture from sample output. Used by `--write-fixture`\n * to seed a first draft the author can hand-tune.\n *\n * Heuristics:\n * - rowCount.min = 1 if rows non-empty, else 0\n * - columns = keys from the first row\n * - types = typeof of the first row's values, with \"number|string\" for mixed","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/src/browser/verify-fixture.ts#L104-L140","documentation":"loadFixture reads a fixture JSON file for a site/command pair and parses it. If the file exists but is unreadable or is not valid JSON, the low-level error is wrapped in a descriptive Error naming the fixture path and the parse failure, so callers know exactly which fixture is corrupt.","triggerScenarios":"The fixture file at fixturePath(site, command) exists but contains malformed JSON (trailing commas, truncated writes, hand-edited syntax errors) or cannot be read (permissions, encoding).","commonSituations":"Manually editing a fixture and breaking JSON; a crashed run leaving a half-written fixture via writeFixture; fixtures committed with BOM or comments; concurrent runs corrupting the file.","solutions":["Open the path from the error message and fix the JSON syntax (validate with jq or a JSON linter).","Delete the corrupt fixture and regenerate it with writeFixture by re-running the command that produces it.","Check file permissions/readability if the wrapped message is a read error rather than a parse error.","Verify the file has no BOM, comments, or trailing commas."],"exampleFix":"// before (fixtures/foo.json)\n{ \"steps\": [1, 2,] }\n// after\n{ \"steps\": [1, 2] }","handlingStrategy":"fallback","validationCode":"import { readFileSync, existsSync } from 'fs';\nfunction fixtureLooksValid(p) {\n  if (!existsSync(p)) return true;\n  try { JSON.parse(readFileSync(p, 'utf-8')); return true; } catch { return false; }\n}","typeGuard":"function isFixture(v: unknown): v is Fixture {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const fixture = loadFixture(site, command);\n} catch (err) {\n  console.error(err.message);\n  // regenerate the corrupt fixture\n  writeFixture(site, command, defaultFixture);\n  fixture = defaultFixture;\n}","preventionTips":["Validate fixture JSON with jq after hand edits.","Always let writeFixture serialize fixtures instead of editing them manually.","Treat fixture files as generated artifacts; regenerate rather than repair.","Watch for concurrent runs writing the same fixture path."],"tags":["json","fixture","parse","filesystem"],"backgroundTag":"json-parse-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}