Skip to content

fix(cdk): PDF attachment screening broken — ambient pdf-parse decl describes v1 API against installed v2 #683

Description

@scottschreckengaust

Discovered while reviewing PR #673 (#607). Pre-existing — landed in #434 (2026-06-30), not introduced by #673.

Symptom

PDF attachment screening fails for all `application/pdf` inputs. Every PDF is reported as `PDF "" could not be processed. It may be corrupt or use unsupported features.` — indistinguishable from a genuinely corrupt file, so the failure is silent.

Root cause

`cdk/src/types/pdf-parse.d.ts` is an ambient `declare module 'pdf-parse'` describing the v1 API:

```ts
function pdfParse(data: Buffer, options?: { max?: number }): Promise;
export = pdfParse;
```

The installed package is `[email protected]`, which exports no callable default:

```
$ node -e "const m=require('pdf-parse'); console.log(Object.keys(m)); console.log(typeof m.default)"
[ 'AbortException', ..., 'PDFParse', 'VerbosityLevel', 'getException' ]
undefined
```

The ambient declaration overrides v2's real bundled types (`dist/pdf-parse/cjs/index.d.cts`), so `tsc` stays green against a shape that no longer exists. At runtime, in `cdk/src/handlers/shared/attachment-screening.ts`:

  • `pdfParseFn = (mod as any).default ?? mod` resolves to the module namespace object (no default export).
  • Calling `pdfParseFn(content, { max })` throws `TypeError: pdfParseFn is not a function`, which is caught and rewrapped as the generic "could not be processed" error.

The test at `cdk/test/handlers/shared/attachment-screening.test.ts:365` uses a `{ virtual: true }` mock supplying `{ __esModule: true, default: jest.fn() }` — a v1 shape that no longer exists — so the suite cannot catch this.

Fix

  • Delete `cdk/src/types/pdf-parse.d.ts` and let v2's own bundled types apply.
  • Rewrite the call site to the v2 API: `new PDFParse({ data: content }).getText()` returning a `TextResult`.
  • Replace the virtual mock with one reflecting the real v2 module (a `PDFParse` class with a `getText()` method), and add a test that exercises a real (small) PDF end-to-end so a future API mismatch fails loudly.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinginfra-cdkCDK stacks/constructs, bootstrap, deploy topology, tags, IAM wiring, teardownsecurityCedar/HITL, IAM least-privilege, secrets, PII/DLP, guardrails, supply-chain/CVE

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions