{"record":{"id":"9c91d7bc0af8dad0","repo":"jlcodes99/cockpit-tools","slug":"messages-invalidjson","errorCode":null,"errorMessage":"messages.invalidJson","messagePattern":"messages\\.invalidJson","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/hooks/useProviderAccountsPage.ts","lineNumber":385,"sourceCode":"        return lineDelimitedItems;\n      }\n    } catch (error) {\n      lineDelimitedError = error;\n    }\n\n    if (platformId === 'codex') {\n      try {\n        const rawRefreshTokenItems = parseCodexRawRefreshTokenItems(rawContent, messages);\n        if (rawRefreshTokenItems && rawRefreshTokenItems.length > 0) {\n          return rawRefreshTokenItems;\n        }\n      } catch (error) {\n        throw error;\n      }\n    }\n\n    if (lineDelimitedError) throw lineDelimitedError;\n    throw new Error(messages.invalidJson);\n  }\n\n  if (parsed && typeof parsed === 'object' && 'code' in parsed) {\n    const code = (parsed as { code?: unknown }).code;\n    if (code !== 200 && code !== '200') {\n      throw new Error(\n        readBundleMessage((parsed as { msg?: unknown }).msg) ??\n          readBundleMessage((parsed as { message?: unknown }).message) ??\n          readBundleMessage((parsed as { error?: unknown }).error) ??\n          messages.empty,\n      );\n    }\n  }\n\n  const root =\n    parsed && typeof parsed === 'object' && 'data' in parsed\n      ? (parsed as { data?: unknown }).data\n      : parsed;","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/hooks/useProviderAccountsPage.ts#L367-L403","documentation":"resolveExternalImportBundleItems could not interpret the imported content as JSON at all: whole-content JSON.parse failed, the line-delimited fallback threw or produced nothing, and (for codex) the raw refresh-token fallback did not apply or returned nothing. messages.invalidJson is the terminal 'not parseable' error (line 385).","triggerScenarios":"Content is neither valid JSON, nor >=2 lines of JSON objects, nor (for codex) token-bearing raw lines; also thrown for codex when the line-delimited parse failed with fewer than 2 lines and the raw fallback returned null (e.g. only whitespace).","commonSituations":"Uploading an empty or whitespace-only file; pasting HTML from a failed export page; binary/corrupted download; wrong clipboard content; a YAML/CSV export pasted into a JSON-only importer.","solutions":["Verify the content is valid JSON by running it through JSON.parse or a validator","Re-export the bundle from the source tool instead of hand-copying","Check the file/clipboard is not empty, truncated, or HTML","For codex, supply lines each containing exactly one rt_... token if using raw format"],"exampleFix":"// before (not JSON)\naccounts: [a, b]\n// after\n{\"items\":[{\"refresh_token\":\"rt_a\"},{\"refresh_token\":\"rt_b\"}]}","handlingStrategy":"validation","validationCode":"if (!content || !content.trim()) throw new Error('Import content is empty');\ntry { JSON.parse(content); } catch { /* may still be raw token format for codex */ }","typeGuard":"const looksParseable = (content: string): boolean =>\n  content.trim().startsWith('{') || content.trim().startsWith('[');","tryCatchPattern":"try {\n  items = resolveExternalImportBundleItems(content, platformId, messages);\n} catch (e) {\n  if (e instanceof Error && e.message === messages.invalidJson) {\n    showFormatHelp();\n  }\n}","preventionTips":["Verify content is non-empty and valid JSON before importing","Re-export from the source tool instead of manual copying","Check the clipboard/file actually holds the export, not HTML or another format"],"tags":["json","parsing","import","empty-input"],"backgroundTag":"invalid-json-input","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"}