Stirling-Tools/Stirling-PDF · warning · Error

File is not valid JSON

Error message

File is not valid JSON: ${(err as Error).message}

What it means

Thrown by parseAutomationFile when JSON.parse rejects the file text. The original SyntaxError is attached as cause. The file content is not valid JSON.

Solutions

  1. Confirm the file is genuinely JSON by opening it in a text editor.
  2. Strip a leading UTF-8 BOM before parsing.
  3. Validate with a JSON linter.
  4. Surface cause.message to the user for the parse position.

Example fix

// before
raw = JSON.parse(fileText);

// after
const clean = fileText.replace(/^\uFEFF/, '').trim();
if (!clean.startsWith('{') && !clean.startsWith('[')) {
  throw new Error('File does not look like JSON (unexpected first character).');
}
raw = JSON.parse(clean);
Defensive patterns

Strategy: try-catch

Validate before calling

const clean = fileText.replace(/^\uFEFF/, '').trim();
if (!clean.startsWith('{') && !clean.startsWith('[')) {
  throw new Error('Selected file is not JSON.');
}

Type guard

function looksLikeJson(text: string): boolean {
  const t = text.replace(/^\uFEFF/, '').trim();
  return t.startsWith('{') || t.startsWith('[');
}

Try / catch

try {
  return parseAutomationFile(text, toolRegistry, expectedFormat);
} catch (e) {
  if (e instanceof Error && /not valid JSON/i.test(e.message)) {
    throw new Error('The selected file is not valid JSON. Please choose an exported automation config.');
  }
  throw e;
}

Prevention

When it happens

Trigger: The file content is not parseable JSON: an HTML error/login page saved as .json, a truncated download, a UTF-8 BOM, binary, or CSV content.

Common situations: Downloaded an HTML error or login page instead of the config; user picked a non-JSON file; encoding/BOM issues; a truncated download.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/98f6687929002cb9. Report an issue: GitHub.

Appendix: source

Thrown at frontend/editor/src/core/utils/automationConverter.ts:394

  if (hasOperations && !hasPipeline) return "automate";
  return "unknown";
}

/**
 * Parse a JSON file's text content into a normalized AutomationConfig.
 * Auto-detects the format unless `expectedFormat` is supplied; throws with a
 * user-readable message on any structural problem.
 */
export function parseAutomationFile(
  fileText: string,
  toolRegistry: Partial<ToolRegistry>,
  expectedFormat?: "automate" | "folderScanning",
): ParsedAutomationImport {
  let raw: unknown;
  try {
    raw = JSON.parse(fileText);
  } catch (err) {
    throw new Error(`File is not valid JSON: ${(err as Error).message}`, {
      cause: err,
    });
  }

  const detected = detectAutomationFormat(raw);
  const format = expectedFormat ?? detected;

  if (expectedFormat && detected !== "unknown" && detected !== expectedFormat) {
    throw new Error(
      `Expected ${
        expectedFormat === "automate"
          ? "Automate JSON (operations array)"
          : "Folder Scanning JSON (pipeline array)"
      } but file looks like ${
        detected === "automate" ? "Automate JSON" : "Folder Scanning JSON"
      }.`,
    );
  }

View on GitHub (pinned to 9ef20dcab8)