Skip to content

Fix stuck PDF extraction task that permanently blocks new scans (live E2E bugs 3 & 4) - #49

Merged
warrendt merged 1 commit into
mainfrom
e2e-verification
Aug 9, 2026
Merged

Fix stuck PDF extraction task that permanently blocks new scans (live E2E bugs 3 & 4)#49
warrendt merged 1 commit into
mainfrom
e2e-verification

Conversation

@warrendt

@warrendt warrendt commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Live end-to-end testing against the deployed app (Playwright, authenticated via Easy Auth) reproduced the originally reported bugs 3 and 4 exactly.

What was found

Choosing a PDF hit "⚠️ A PDF extraction task is already in progress" with no way to clear it. Backend logs showed the click never reached the extraction endpoint at all — the block was purely client-side. Neither "Clear workspace" (Home) nor "Clear & Start Over" (PDF page) freed it. A minimal, isolated reproduction (network capture, no test-harness cleverness) showed the 1 active task: PDF Extraction 20% banner reappear immediately after a successful DELETE /api/v1/session/all.

Root cause

pdf_extraction tasks register with poll_backend=False — they're updated only by the Streamlit fragment on the page that started them (_render_active_pdf_extraction). If that page is navigated away from, reloaded, or the tab is closed mid-extraction, nothing ever calls update_task() again, so the entry stays "running" forever. poll_active_tasks() explicitly skips these ("Frontend-managed tasks are updated by the page itself"), so there is no backend reconciliation path at all.

"Clear workspace" was also gated on controls or mappings or policy only, so a workspace with nothing but a stuck task rendered the button disabled.

Fix

  • get_active_tasks() / has_active_task_of_type() now expire a poll_backend=False task after 30 minutes with no update — comfortably above the 5-9 minutes a real extraction has taken in practice. Expiry is honest, not silent: the task is marked failed with an explanatory error, not silently dropped.
  • "Clear workspace" now also enables when there's an active task, and explicitly cancels active tasks before resetting so each gets a real "cancelled" transition rather than vanishing.

Verified

  • 5 new regression tests (app/tests/test_task_staleness.py), wired into CI: recent tasks stay active, abandoned ones expire honestly, a stale task no longer blocks a fresh scan, backend-polled tasks are untouched by the staleness check (only the poll_backend=False escape hatch is affected), and a malformed timestamp doesn't crash the check.
  • Existing frontend suite (test_state_init_helpers.py, test_policy_display.py, test_column_mapping.py, test_pdf_upload_state.py) still passes — 26/26.

Also in this PR

docs/BACKLOG.md: confirmed B1 (PDF-path hardcoded GUIDs) is already fixed by the merged mapping-engine-rework work (policy_mapper.py now delegates to AIMappingService); updated B2 status; recorded this fix as B7.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com
Copilot-Session: f9597648-5968-478c-a4a0-b0bd88074134

…new scans

Live E2E testing reproduced the user's bugs 3 and 4 exactly: choosing a PDF
hit "A PDF extraction task is already in progress" with no way to clear it.
Backend logs showed the click never reached the extraction endpoint at all -
the block was purely client-side. Neither "Clear workspace" nor "Clear &
Start Over" freed it: a minimal, isolated reproduction showed the "1 active
task: PDF Extraction 20%" banner reappear immediately after a successful
DELETE /api/v1/session/all.

Root cause: pdf_extraction tasks register with poll_backend=False - they are
updated only by the Streamlit fragment on the page that started them. If that
page is navigated away from, reloaded, or the tab closed mid-extraction,
nothing ever calls update_task() again, so the entry stays "running" forever.
poll_active_tasks() explicitly skips these tasks ("Frontend-managed tasks are
updated by the page itself"), so there is no backend reconciliation path at
all. "Clear workspace" was also gated on controls/mappings/policy only, so a
workspace with nothing but a stuck task rendered the button disabled.

Fixes:
- get_active_tasks() / has_active_task_of_type() now expire a poll_backend=
  False task after 30 minutes with no update (real extractions have taken
  5-9 minutes in practice) - honesty over silence: the task is marked failed
  with an explanatory error, not silently dropped.
- "Clear workspace" enables whenever there is an active task too, not just
  controls/mappings/policy, and explicitly cancels active tasks before
  resetting so each gets a real "cancelled" transition.

5 new regression tests in app/tests/test_task_staleness.py, wired into CI.
Also updates docs/BACKLOG.md: B1 (hardcoded PDF-path GUIDs) confirmed already
fixed by the merged mapping-engine-rework work; B2 (runner credential) status
updated; B7 (this fix) recorded.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f9597648-5968-478c-a4a0-b0bd88074134
@warrendt
warrendt merged commit 3a26ee2 into main Aug 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant