## TL;DR

Faded thermal receipts fall below the OCR contrast threshold, so the engine returns nothing. Preprocess the image (grayscale, contrast stretch, upscale 2x) before OCR, and route anything still empty to a human review queue instead of failing the run.

## Error

```text
agent failed to read faded receipt: ocr returned empty
```

## Steps

1. Inspect a failing receipt image: check whether any text is visible to the human eye. Expected: faint but present text, or truly blank paper.
2. Add a preprocessing step before OCR: convert to grayscale, apply contrast stretching, and upscale to at least 300 DPI equivalent. Expected: the same image now shows stronger text edges.
3. Re-run OCR on the preprocessed image. Expected: text is extracted where the raw image returned empty.
4. For images that still return empty, push the expense to a manual-review queue with the image attached. Expected: a human reads what the OCR cannot.
5. Log the empty-OCR rate per vendor to identify systematic faded-receipt sources. Expected: a short list of vendors to handle manually by default.

## When to use

- Agent OCR returns empty on faded or low-contrast receipts.
- The receipt is legible to a human but not to the OCR engine.

## When not to use

- The receipt is physically crumpled or torn (see the thermal-paper skill).
- OCR returns garbage text rather than empty (see the OCR-garbage skill).

## Tool compatibility

- Tesseract, cloud OCR APIs, and custom agent OCR pipelines.

## Variant phrasings

### OCR returned no text for receipt

Same failure, alternate wording.

### Empty OCR result on faded receipt

Names the cause directly.

## Why it happens

OCR engines threshold on contrast: faded thermal ink sits below the binarization cutoff, so the engine sees a blank page. Preprocessing raises the text above the threshold before recognition runs.

## Provenance

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