aws-samples / aws-samples/sample-autonomous-cloud-coding-agents
fix(cdk): PDF attachment screening broken — ambient pdf-parse decl describes v1 API against installed v2
- Dominant language
- TypeScript
- Stars
- 143
- Forks
- 46
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 20
Description
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 \`pdf-parse@2.4.5\`, 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.
Contributor guide
Research direction
Start with cdk/src/handlers/shared/attachment-screening.ts and cdk/src/types/pdf-parse.d.ts, then inspect the existing mock and test at cdk/test/handlers/shared/attachment-screening.test.ts:365. Verify the installed pdf-parse@2.4.5 API, update the call and mock to match it, and add a small real-PDF test. Done means PDFs are screened successfully, API mismatches fail in tests, and the ambient v1 declaration is gone.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100