jlcodes99/cockpit-tools · error

invalid_json

invalid_json

Error message

invalid_json

What it means

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.

Solutions

  1. Validate the string with JSON.parse locally first to get the exact position of the syntax error.
  2. Re-export the data or obtain the complete original file and retry the import.
  3. Strip BOM/trailing whitespace and confirm the content starts with { or [ before importing.

Example fix

// before
await importDataTransferJson(userPastedText, options);
// after
try { JSON.parse(userPastedText); } catch (e) { alert('Not valid JSON: ' + e.message); return; }
await importDataTransferJson(userPastedText, options);
Defensive patterns

Strategy: validation

Validate before calling

function isValidJson(text) {
  try { JSON.parse(text); return true; } catch { return false; }
}
if (!isValidJson(jsonContent)) { alert('File is not valid JSON'); return; }

Try / catch

try {
  await importDataTransferJson(jsonContent, options);
} catch (e) {
  if (e.message === 'invalid_json') {
    try { JSON.parse(jsonContent); } catch (pe) { console.error('JSON syntax error at:', pe.message); }
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/1ba270c51b846f61. Report an issue: GitHub.

Appendix: source

Thrown at src/services/dataTransferService.ts:371

  return null;
}

function stringEquals(left: unknown, right: unknown): boolean {
  const normalizedLeft = normalizeString(left)?.toLowerCase();
  const normalizedRight = normalizeString(right)?.toLowerCase();
  return Boolean(normalizedLeft && normalizedRight && normalizedLeft === normalizedRight);
}

function stringContains(value: unknown, keyword: string): boolean {
  const normalized = normalizeString(value)?.toLowerCase();
  return Boolean(normalized && normalized.includes(keyword.toLowerCase()));
}

function parseJsonOrThrow(jsonContent: string, errorCode: string): unknown {
  try {
    return JSON.parse(jsonContent) as unknown;
  } catch {
    throw new Error(errorCode);
  }
}

function safeGetLocalStorageItem(key: string): unknown {
  const value = localStorage.getItem(key);
  if (!value) return undefined;
  try {
    return JSON.parse(value);
  } catch {
    return value;
  }
}

function safeSetLocalStorageItem(key: string, value: unknown): void {
  if (value === null || value === undefined) {
    localStorage.removeItem(key);
  } else if (typeof value === 'string') {
    localStorage.setItem(key, value);

View on GitHub (pinned to 1ed8b77992)