{"record":{"id":"bd9912595c27e34e","repo":"dmtrKovalenko/fff","slug":"not-valid-json-errormessage-error","errorCode":null,"errorMessage":"not valid JSON (${errorMessage(error)})","messagePattern":"not valid JSON \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/pi-fff/src/config.ts","lineNumber":49,"sourceCode":"\nexport function loadConfig(agentDir = piDataDir()): FffConfig {\n  const configPath = join(agentDir, CONFIG_FILE_NAME);\n  let contents: string;\n\n  try {\n    contents = readFileSync(configPath, \"utf8\");\n  } catch (error: unknown) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n    throw new Error(\n      `Could not read pi-fff config at ${configPath}: ${errorMessage(error)}`,\n    );\n  }\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(contents);\n  } catch (error: unknown) {\n    throw invalidConfig(configPath, `not valid JSON (${errorMessage(error)})`);\n  }\n\n  if (!isRecord(parsed)) {\n    throw invalidConfig(configPath, \"expected a JSON object\");\n  }\n\n  for (const key of Object.keys(parsed)) {\n    if (!CONFIG_KEYS.has(key as keyof FffConfig)) {\n      throw invalidConfig(configPath, `unknown option \"${key}\"`);\n    }\n  }\n\n  if (parsed.mode !== undefined && !VALID_MODES.includes(parsed.mode as FffMode)) {\n    throw invalidConfig(configPath, `\"mode\" must be one of ${VALID_MODES.join(\", \")}`);\n  }\n\n  validateString(configPath, parsed, \"$schema\");\n  validateString(configPath, parsed, \"frecencyDbPath\");","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/packages/pi-fff/src/config.ts#L31-L67","documentation":"loadConfig read the fff config file successfully but JSON.parse threw, so the file contents are not valid JSON. The original parse error is embedded in the message (\"not valid JSON (...)\") to help locate the syntax problem. The library treats any malformed config as fatal rather than silently ignoring user settings.","triggerScenarios":"Calling config()/loadConfig when the config file at configPath contains a JSON syntax error: trailing commas, comments (JSON5-style //), single quotes, unquoted keys, truncated writes, or BOM/control characters.","commonSituations":"Hand-editing the config and leaving a trailing comma; tools that wrote a partial file during a crash; copying a JSONC config with comments into a strict-JSON loader; a previous version wrote config in a different format.","solutions":["Open the path from the error and fix the JSON syntax — run it through JSON.parse or a linter to find the exact spot.","Remove JSONC-only constructs (comments, trailing commas) or switch the file to strict JSON.","Restore the file from backup or delete it so the library regenerates defaults.","Validate the config with a JSON schema/JSON.parse in CI to catch breakage early."],"exampleFix":"// before (config.json)\n{\n  \"keymaps\": { \"open\": \"<leader>ff\", }, // trailing comma + comment\n}\n// after\n{\n  \"keymaps\": { \"open\": \"<leader>ff\" }\n}","handlingStrategy":"try-catch","validationCode":"const contents = fs.readFileSync(configPath, 'utf8').replace(/^\\uFEFF/, '');\ntry { JSON.parse(contents); } catch (e) { throw new Error(`${configPath} is not valid JSON: ${e.message}`); }","typeGuard":null,"tryCatchPattern":"try {\n  cfg = config(configPath);\n} catch (e) {\n  if (/not valid JSON/.test(e.message)) {\n    console.error(`Fix syntax in ${configPath}; falling back to defaults`);\n    cfg = defaultConfig;\n  } else throw e;\n}","preventionTips":["Lint the config file as strict JSON (no comments, no trailing commas) in CI.","Strip BOM before parsing if files may come from Windows editors.","Write config atomically (temp file + rename) to avoid truncated files.","Keep a known-good backup of the config."],"tags":["config","json","parse"],"backgroundTag":"json-parse-error","analyzedSha":"7f8537e70f0ea1210f9acbbfc4640141105cdc78","analyzedAt":"2026-09-10T07:26:53.407Z","contentChangedAt":"2026-09-10T07:26:53.407Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}