Stirling-Tools/Stirling-PDF · error · RuntimeError

No glyphs provided in input JSON

Error message

No glyphs provided in input JSON

What it means

type3_to_cff.py synthesises an OpenType CFF font from a glyph JSON emitted by the backend. After iterate_glyphs(data) builds the glyph list, it raises RuntimeError at line 348 if no usable glyph was produced, rather than building an empty font (which fontTools would reject downstream). iterate_glyphs (line 138) skips non-dict records, so results is empty when the `glyphs` key is absent, an empty array, or contains only non-object entries. It signals the input is not a real font dump.

Source

Thrown at scripts/type3_to_cff.py:348

            if ttf_glyph is not None:
                ttf_glyph.width = width
        if bounds is not None:
            global_y_min = min(global_y_min, bounds[1])
            global_y_max = max(global_y_max, bounds[3])
        results.append(
            GlyphBuildResult(
                name=glyph.name,
                width=width,
                charstring=charstring,
                ttf_glyph=ttf_glyph,
                unicode=glyph.unicode,
                char_code=glyph.char_code,
                bounds=bounds,
            )
        )

    if not results:
        raise RuntimeError("No glyphs provided in input JSON")

    ascent = global_y_max if math.isfinite(global_y_max) else units_per_em * 0.8
    descent = global_y_min if math.isfinite(global_y_min) else -units_per_em * 0.2
    ascent = otRound(ascent)
    descent = otRound(descent)
    if ascent <= 0:
        ascent = otRound(units_per_em * 0.8)
    if descent >= 0:
        descent = -otRound(units_per_em * 0.2)

    glyph_order = [".notdef"] + [result.name for result in results]
    horizontal_metrics = {result.name: (result.width, 0) for result in results}
    horizontal_metrics[".notdef"] = (default_width, 0)

    cmap: dict[int, str] = {}
    next_private = 0xF000
    for result in results:
        code_point = result.unicode

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Inspect the input to confirm a non-empty glyphs array: `python -c "import json;d=json.load(open('<file>'));print(len(d.get('glyphs',[])))"`
  2. Verify the input is a raw glyph dump (has top-level `glyphs` and `fontMatrix`) and not a different JSON artifact such as the inventory produced by summarize_type3_signatures.py
  3. If the backend key changed, remap it before running, or regenerate the dump from the current backend version

Example fix

# before (type3_to_cff.py main, calls synthesise_fonts blindly)
data = load_json(input_path)
synthesise_fonts(data=data, otf_output=otf_output, ...)

# after -- validate glyph presence before the heavy build
data = load_json(input_path)
records = data.get("glyphs")
if not isinstance(records, list) or not records:
    raise SystemExit(f"{input_path} has no non-empty 'glyphs' array; nothing to synthesise")
synthesise_fonts(data=data, otf_output=otf_output, ...)
Defensive patterns

Strategy: validation

Validate before calling

data = load_json(input_path)
records = data.get("glyphs")
if not isinstance(records, list) or not records:
    raise SystemExit(f"{input_path} has no non-empty 'glyphs' array; nothing to synthesise")

Type guard

def has_glyphs(data: dict[str, object]) -> bool:
    records = data.get("glyphs")
    return isinstance(records, list) and any(isinstance(r, dict) for r in records)

Try / catch

try:
    synthesise_fonts(data=data, otf_output=otf_output, ...)
except RuntimeError as exc:
    print(f"ERROR: {exc}", file=sys.stderr)
    sys.exit(1)

Prevention

When it happens

Trigger: Passing a JSON with no `glyphs` key, an empty `glyphs` array, or a schema variant where glyphs live under a different key; the backend emitted a font record for a Type3 font that contained zero glyphs; pointing --input at a summary/inventory JSON instead of a raw glyph dump.

Common situations: Schema drift between the backend extractor and this script; testing with a stub JSON fixture; a PDF whose Type3 font legitimately has no glyphs.

Related errors


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