Repository navigation
Ingestion guide's AWS Textract recipe reads only the first GetDocumentTextDetection page and never checks JobStatus, silently truncating multi-page OCR text (F-W1-DOCS-TRAIN-13) #883
Description
Wave 3 · group W3 Docs · highest severity Medium · 1 finding(s) · effort docs fix
Summary
The OCR recipe makes one get_document_text_detection call, writes the LINE blocks it returns and runs forgelm ingest on the result. Textract returns at most 1,000 blocks per call — PAGE, LINE and WORD blocks all count — plus a NextToken for the rest, so a typical multi-page scan is cut short with no error and the truncated text becomes training data.
Primary finding
F-W1-DOCS-TRAIN-13 — The Textract recipe silently truncates paginated OCR output
severity Medium · confidence high · checked against the AWS API reference
What happens. docs/guides/ingestion.md:634-650 (Turkish mirror docs/guides/ingestion-tr.md:652-668); the single call is at EN :644 / TR :662. The snippet never follows NextToken and never checks JobStatus, so a job that is still IN_PROGRESS, FAILED or only a PARTIAL_SUCCESS looks the same as a finished one. It also uses $JOB_ID without showing where it comes from: the start-document-text-detection call in step 2 does not capture the returned JobId.
Where.
docs/guides/ingestion.md:634-650(single call at :644)docs/guides/ingestion-tr.md:652-668(single call at :662)
Evidence (re-verified on 2026-10-09).
- AWS Textract API reference, GetDocumentTextDetection: results are paginated; when a response includes
NextToken, call the operation again with it to get the next set;MaxResultsdefaults to 1,000 (https://docs.aws.amazon.com/textract/latest/APIReference/API_GetDocumentTextDetection.html). - The source review ran the embedded snippet against a two-page stub client: it made one call, printed only the first page and exited normally.
- Both guide pages are unchanged on
development.
Recommended fix. Capture the job id (JOB_ID=$(aws textract start-document-text-detection … --query JobId --output text)), wait until JobStatus is no longer IN_PROGRESS (or point to AWS's polling / SNS pattern), stop with an error on FAILED, print a warning on PARTIAL_SUCCESS, and loop over NextToken so every page's LINE blocks are written in order before forgelm ingest runs.
Acceptance criteria
- The recipe follows
NextTokenuntil it is absent and writes every LINE block in order. - A failed or still-running job stops the recipe before
forgelm ingest; a partial success is reported. - The snippet shows where
JOB_IDcomes from. - Documentation listed above is corrected in English and in its Turkish mirror in the same PR.
- The finding is resolved or explicitly closed with a reason.
Found by the September 2026 independent review of ForgeLM against commit cab2947 and re-verified against development at f94595f on 2026-10-09. Code links point at cab2947; line numbers may have moved since. Finding IDs (F-W1-…) are stable references for this backlog.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
cemililik commentedon Oct 11, 2026
Where to start
Thanks for taking a look. Please confirm the issue is unassigned and comment before starting so work does not overlap.
Start with these files on
development:Capture JobId from the start response, wait for SUCCEEDED, reject failed/partial jobs explicitly, and follow every NextToken before ingesting LINE text. Verify the example with a local stub returning IN_PROGRESS then two result pages and a failure case; AWS credentials/network must not be needed for verification. Follow the linked AWS API contract.
Documentation recipe only; no new OCR backend or AWS dependency in ForgeLM.
Run the focused tests:
Run these guards/checks as applicable to the changed files:
If user-facing documentation changes, update the existing Turkish mirror in the same PR; keep commands, code and terminal output in English and structurally aligned. English-only contributor standards need no new mirror.
Open the PR against
developmentwithFixes #883once every finding is resolved or explicitly closed with a reason; useRefs #883for partial work and list the resolved finding IDs.cemililik commentedon Oct 17, 2026
Update — re-verified on
development(0766e94). The recipe is unchanged.To save you a choice: treat
PARTIAL_SUCCESSlikeFAILED— print the status and stop witha non-zero exit before
forgelm ingest, because training data must not be silentlyincomplete. The step-2 comment that says polling is out of scope will no longer be true;
reword it.
No test file changes: the
pytest/rufflines above are only a sanity run. In the Turkishblock you may keep the English comments.