# Fix pdfminer.six "PSParseError" on a contract with embedded form fields

## TL;DR
pdfminer.six's content-stream parser chokes on the operators Acrobat writes for AcroForm fillable fields, so contracts with form fields fail to parse. Flatten the form first: bake each widget's appearance into static page content with PyMuPDF and save a form-free copy, then parse that copy with pdfminer.six.

```text
PSParseError
```

## Steps
1. Confirm form fields are the trigger: list AcroForm widgets (for example, PyMuPDF's document widgets call, or qpdf --json).
   Expected: one or more form fields listed; files without fields parse fine.
2. Flatten: use PyMuPDF to bake each widget's visual appearance into its page, remove the form, and save a new PDF.
   Expected: the new file has no AcroForm structure; widgets are now static content.
3. Parse the flattened file with your existing pdfminer.six code.
   Expected: text extracts without PSParseError.
4. Alternative path: extract the text with PyMuPDF directly, which tolerates the form constructs natively.
   Expected: clean text with no flattening step needed.

## Use this when
- pdfminer.six raises PSParseError on a contract that contains fillable form fields
- The same pipeline parses non-form contracts fine
- A counterparty sends "fillable" PDFs that break your extractor

## Not for this skill when
- pdfminer.six fails on files with no form fields (that's a different parser bug; try another library)
- You need the field values as structured data (flattening bakes them visually; read widgets programmatically instead)
- The PDF won't open at all (that's a corruption problem)

## Variant phrasings
### pdfminer six parse error acroform
AcroForm appearance streams are the usual trigger; flatten first.
### pdfminer.six fails on fillable pdf
Same fix: bake widgets into the page, then parse.
### extract text from pdf form fields python
Read field values via the widget API if you need data; flatten if you need page text.

## Why it happens
AcroForm fields store their visual appearance in XObject streams using operators and nesting that pdfminer.six's PostScript-style content parser doesn't handle. The parser was built for page content streams; form appearance streams are a related but different construct, and the mismatch raises PSParseError.

## Edge cases
- Signature fields can't be flattened the same way; treat them separately and don't expect their content as text.
- Read-only fields still carry appearance streams and still trip the parser; flatten regardless of editability.
- Flattening is lossy for form data structure; if you need field names and values, extract via the widget API before flattening.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_Tn1x8Rr9HE1BS0frsxgFfg
