Stirling-Tools/Stirling-PDF · warning · SystemExit
Unexpected JSON structure (expected an object at root).
Error message
Unexpected JSON structure (expected an object at root).
What it means
SystemExit raised by analyze_pdf_json.py when the parsed JSON root is not an object (dict). The analyzer expects a Stirling PDF JSON export whose root is an object containing keys like fonts, pages, metadata. A JSON array, primitive, or malformed export at the root fails this check.
Source
Thrown at scripts/analyze_pdf_json.py:221
def main() -> None:
parser = argparse.ArgumentParser(description="Inspect a PDF JSON export.")
parser.add_argument("json_path", type=Path, help="Path to the JSON export.")
args = parser.parse_args()
json_path = args.json_path
if not json_path.exists():
raise SystemExit(f"File not found: {json_path}")
file_size = json_path.stat().st_size
print(f"File: {json_path}")
print(f"Size: {human_bytes(file_size)} ({file_size:,} bytes)")
with json_path.open("r", encoding="utf-8") as handle:
document = json.load(handle)
if not isinstance(document, dict):
raise SystemExit("Unexpected JSON structure (expected an object at root).")
summary = analyze_document(document, file_size)
page_stats = summary.pages
print(f"Pages: {page_stats.page_count}")
print(f"Total text elements: {page_stats.total_text_elements:,}")
print(f"Total image elements: {page_stats.total_image_elements:,}")
print(
f"Page structural bytes (text arrays + images + streams + annotations): "
f"{human_bytes(page_stats.text_struct_bytes + page_stats.image_struct_bytes + page_stats.content_stream_bytes + page_stats.annotations_bytes)}"
)
font_stats = summary.fonts
print("\nFont summary:")
print(f" Fonts total: {font_stats.total}")
print(f" Fonts with cosDictionary: {font_stats.with_cos}")
print(f" Fonts with program: {font_stats.with_program}")
print(f" Fonts with webProgram: {font_stats.with_web_program}")
print(f" Fonts with pdfProgram: {font_stats.with_pdf_program}")View on GitHub (pinned to 9ef20dcab8)
Solutions
- Confirm the file is a Stirling PDF text-editor JSON export (should have top-level 'pages', 'fonts', 'metadata').
- Re-export the PDF from the editor.
- Inspect the file root with: python -c "import json;print(type(json.load(open('file.json'))))".
Defensive patterns
Strategy: validation
Validate before calling
# Confirm the root is an object with expected keys before analysis
if not isinstance(document, dict) or not {"pages", "fonts"} <= document.keys():
raise SystemExit("Not a Stirling PDF JSON export (missing pages/fonts at root).") Type guard
def is_pdf_export(document: object) -> bool:
return isinstance(document, dict) and "pages" in document and "fonts" in document Prevention
- Confirm the file is a Stirling PDF export (has pages/fonts at root).
- Re-export from the editor if the structure is wrong.
- Inspect the root type before analysis.
When it happens
Trigger: The file contains valid JSON but the root is an array (e.g. a list of pages) or a scalar, not the expected object shape. The file is a different JSON format mistaken for a PDF export.
Common situations: Pointing the analyzer at the wrong JSON file (e.g. a raw page array export, a config file). A truncated/corrupted export that parsed to a partial structure. An upstream change to the export schema.
Related errors
- File not found: {json_path}
- No URLs supplied. Use --urls and/or --urls-file.
- No PDF files found under the supplied --input paths.
- Invalid folder scanning config: expected JSON object
- Invalid folder scanning config: missing 'pipeline' array
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/6320450b284b5f57.
Report an issue: GitHub.