edof

Troubleshooting

Common issues and how to solve them.

Installation

pip install edof[all] fails

Most likely one of the optional extras (PyQt6, pymupdf, reportlab, cryptography) doesn’t have a wheel for your Python version. Install with a smaller subset and add extras one by one to find the culprit:

pip install edof
pip install edof[crypto]
pip install edof[qr]
pip install edof[pdf]
pip install edof[pyqt6]

The one that fails is the one to investigate. Search for the error message in the failing package’s GitHub issues.

If a wheel doesn’t exist, you may need:

edof-editor not found in PATH

This means either:

Check where the script lives:

# Windows
where edof-editor

# Linux/macOS
which edof-editor

If not found:

import sys, os
print(os.path.dirname(sys.executable))   # Python install directory
# Then find: <that>/Scripts/edof-editor.exe (Windows) or <that>/bin/edof-editor (Linux/macOS)

Add the appropriate Scripts/bin directory to PATH (Environment Variables on Windows; ~/.bashrc on Linux).

ImportError: cryptography when using encryption

pip install edof[crypto]
# or directly:
pip install cryptography>=42

ImportError: pymupdf when calling import_pdf

pip install edof[pdf]

Runtime issues

EdofPasswordRequired when loading

The file is encrypted and needs a password:

doc = edof.load("secret.edof", password="...")

Or with the recovery key:

doc = edof.load("secret.edof", recovery_key="ABCD-EFGH-...")

If you don’t have either, the file is unrecoverable.

EdofWrongPassword

Check:

For recovery keys, dashes and case are ignored. 7K3F-9XQM-2N8P and 7K3F9XQM2N8P work the same.

EdofVersionError when loading

The file was saved by a newer edof version, or the file is corrupt.

Check the version:

from edof.format.serializer import EdofSerializer
manifest = EdofSerializer.peek("file.edof")
print(manifest.get("edof_version"))

If the version is 4.0.x and you have 4.0.0, upgrade:

pip install --upgrade edof

If the file shows no version (raw extraction shows no manifest.json), it might be:

EdofValidationError

You called doc.validate() and it found issues. The exception has a list of problem strings:

issues = doc.validate()
for i in issues:
    print(f"  - {i}")

Common issues and fixes:

Issue Fix
“Required variable X has no value” Call doc.set_variable("X", value) before exporting
“Object Y references resource Z which doesn’t exist” The resource was deleted but objects still reference it. Either re-add the resource or update the object’s resource_id
“Duplicate object ID” Two objects have the same UUID. Re-create one of them with obj.id = new_uuid()
“Object positioned entirely off-page” Check obj.transform.x/y — likely negative or beyond page size

validate() doesn’t fix issues — it just reports them. Always check after building documents programmatically.

Czech / Polish / German diacritics don’t render

The vector PDF writer uses WinAnsiEncoding which covers Czech, Polish, German, etc. fine. If diacritics are missing:

If a specific Unicode character doesn’t render, the font you specified doesn’t have that glyph. Try a different font (DejaVu Sans is the safest default) or use raster output mode.

Custom font in PDF doesn’t work

The vector PDF writer only supports the Standard 14 PDF fonts (Helvetica, Times, Courier with bold/italic variants). Other fonts are mapped to the closest match.

For custom fonts in PDF, use raster mode:

doc.export_pdf("output.pdf", vector=False)

This goes through Pillow which can render any installed TTF.

“Image variable doesn’t update”

If ib.variable = "logo" and you change doc.set_variable("logo", new_path), but the rendered output doesn’t show the new image:

# Verify the variable was set
print(doc.variables.get("logo"))
# Verify the file exists
import os
print(os.path.exists(doc.variables.get("logo")))

“Repeating section overflows the page weirdly”

page.repeat_objects() calculates total height based on the bounding box of the template objects + gap. If your template has an unusual layout (nested groups, overlapping elements), the height may be misjudged.

Workaround: explicitly set a height on the template:

# Template with explicit height
group_template = some_group_with_known_size
group_template.transform.height = 25.0   # mm

# Now repeat_objects knows exactly how much space each repetition needs

“Editor crashes on startup”

Run from a terminal to see error output:

edof-editor

If you see PyQt errors:

If you see edof errors:

“Editor opens but is blank/black”

Often a graphics driver issue:

“Inserted object appears in wrong position”

Coordinates are in mm, with (0, 0) at top-left. Y increases downward. If your object appears upside down or off-page:

“PDF export is much smaller / larger than expected”

Smaller than expected — make sure you’re exporting in the right mode:

doc.export_pdf("out.pdf")              # vector — typically 5-10 KB per page
doc.export_pdf("out.pdf", vector=False) # raster — typically 80-200 KB per page

Larger than expected — usually photographic images. Check your resources:

total = 0
for rid, info in doc.resources.list().items():
    print(f"  {rid}: {info['filename']} {info['size']:,} bytes")
    total += info['size']
print(f"Total resources: {total:,} bytes")

If image sizes are large, downscale them before adding (Pillow can do this in 5 lines).

“Variables in placeholder text not substituted”

Check:

print(doc.variables.values())   # what's currently set?
print(doc.variables.names())     # what's defined?

If the variable is defined but not set, the placeholder remains as {name} and a warning is added to doc.errors.

If you typed {recipient} but defined recipient_name, the names don’t match — placeholders are exact.

EdofMissingFontWarning in doc.errors

A font was requested but not found. Check:

from edof.engine.text_engine import discovered_fonts
print(discovered_fonts())

Either install the font or pick a different one.

The render still happens with a fallback font (DejaVu Sans) — it’s just a warning.


Performance

“Rendering is slow”

Rough times on modern hardware:

If you’re seeing 5+ seconds per page:

“Large batch is slow”

See cookbook/batch-pdf.md for performance tips. Key ones:

“Memory usage grows over time during a long batch”

Possible causes:

Mitigation:

# Periodically restart the worker process
if i % 1000 == 0:
    # ... persist state, restart from clean slate

In practice, memory stays stable for batches of thousands of documents.


File corruption

“File won’t open, says invalid ZIP”

Try standard ZIP recovery tools:

zip -F broken.edof --out fixed.edof

If the ZIP is structurally OK but manifest.json is corrupt:

For encrypted files, manifest corruption usually means the file is unrecoverable. The protection.slots data is critical — without it, no password can unlock the document.

“Document loads but content looks scrambled”

Could be:


Reporting bugs

If you’ve ruled out the issues above:

  1. Try the latest version: pip install --upgrade edof
  2. Reproduce with a minimal example (smallest doc that triggers the issue)
  3. Capture:
    • edof version: python -c "import edof; print(edof.__version__)"
    • Python version: python --version
    • OS and version
    • The minimal example code
    • Full traceback if there’s an exception
  4. Open an issue at https://github.com/DavidSchobl/edof/issues

If the bug involves a specific file, include it (or a redacted/synthetic version that reproduces the issue).


Where to get help