{"record":{"id":"1ba270c51b846f61","repo":"jlcodes99/cockpit-tools","slug":"invalid-json","errorCode":"invalid_json","errorMessage":"invalid_json","messagePattern":"invalid_json","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/dataTransferService.ts","lineNumber":371,"sourceCode":"  return null;\n}\n\nfunction stringEquals(left: unknown, right: unknown): boolean {\n  const normalizedLeft = normalizeString(left)?.toLowerCase();\n  const normalizedRight = normalizeString(right)?.toLowerCase();\n  return Boolean(normalizedLeft && normalizedRight && normalizedLeft === normalizedRight);\n}\n\nfunction stringContains(value: unknown, keyword: string): boolean {\n  const normalized = normalizeString(value)?.toLowerCase();\n  return Boolean(normalized && normalized.includes(keyword.toLowerCase()));\n}\n\nfunction parseJsonOrThrow(jsonContent: string, errorCode: string): unknown {\n  try {\n    return JSON.parse(jsonContent) as unknown;\n  } catch {\n    throw new Error(errorCode);\n  }\n}\n\nfunction safeGetLocalStorageItem(key: string): unknown {\n  const value = localStorage.getItem(key);\n  if (!value) return undefined;\n  try {\n    return JSON.parse(value);\n  } catch {\n    return value;\n  }\n}\n\nfunction safeSetLocalStorageItem(key: string, value: unknown): void {\n  if (value === null || value === undefined) {\n    localStorage.removeItem(key);\n  } else if (typeof value === 'string') {\n    localStorage.setItem(key, value);","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/services/dataTransferService.ts#L353-L389","documentation":"parseJsonOrThrow wraps JSON.parse and re-throws the caller-supplied errorCode ('invalid_json') when the content is not valid JSON. It is used by data import paths that accept user-provided JSON strings. The original SyntaxError message is discarded, so the error carries no parse detail.","triggerScenarios":"Importing a data-transfer or accounts JSON file/string that is empty, truncated, or malformed — e.g. copied partially, saved as non-JSON, or containing trailing commas/comments; passing a non-JSON string (e.g. exported CSV) into an import function.","commonSituations":"Clipboard copy cut off mid-object; file edited by hand and a brace removed; bundlers or editors stripped content; users paste JS object literal with unquoted keys.","solutions":["Validate the string with JSON.parse locally first to get the exact position of the syntax error.","Re-export the data or obtain the complete original file and retry the import.","Strip BOM/trailing whitespace and confirm the content starts with { or [ before importing."],"exampleFix":"// before\nawait importDataTransferJson(userPastedText, options);\n// after\ntry { JSON.parse(userPastedText); } catch (e) { alert('Not valid JSON: ' + e.message); return; }\nawait importDataTransferJson(userPastedText, options);","handlingStrategy":"validation","validationCode":"function isValidJson(text) {\n  try { JSON.parse(text); return true; } catch { return false; }\n}\nif (!isValidJson(jsonContent)) { alert('File is not valid JSON'); return; }","typeGuard":null,"tryCatchPattern":"try {\n  await importDataTransferJson(jsonContent, options);\n} catch (e) {\n  if (e.message === 'invalid_json') {\n    try { JSON.parse(jsonContent); } catch (pe) { console.error('JSON syntax error at:', pe.message); }\n  } else throw e;\n}","preventionTips":["Validate files at the UI boundary (file picker) before handing them to the importer.","Strip BOM and trailing whitespace before parsing.","Never hand-edit exported JSON without re-validating; avoid copy-paste truncation."],"tags":["json","parse","import"],"backgroundTag":"invalid-json","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}