Skip to content

Fix stale second-pass IDs and missing-workflow NREs - #1444

Open
danielgerlag wants to merge 2 commits into
masterfrom
cursor/fix-stale-second-passes-null-workflow-a70f
Open

Fix stale second-pass IDs and missing-workflow NREs#1444
danielgerlag wants to merge 2 commits into
masterfrom
cursor/fix-stale-second-passes-null-workflow-a70f

Conversation

@danielgerlag

Copy link
Copy Markdown
Owner

Fixes #1417
Fixes #1376

Describe the change
Queue items for completed, terminated, or persistence-deleted workflows could still be processed. That produced two related failures:

  • #1417: QueueConsumer._secondPasses kept a workflow id after ExecuteItem finished. A later second pass then tried to process a purged/terminated instance (Sequence contains no elements / missing instance).
  • #1376: With Redis deleteCompleted / removeComplete: true, WorkflowConsumer could dequeue a deleted id. GetWorkflowInstance returned null and Enrich / Status threw NullReferenceException.

Describe your implementation or design
Smallest consumer-side change; no persistence, Redis, or deleteCompleted behavior changes.

  1. In QueueConsumer.ExecuteItem finally, clear _secondPasses alongside _activeTasks.Remove.
  2. After GetWorkflowInstance, if the instance is null, log a warning with the item id and return. Applied in WorkflowConsumer and IndexConsumer (same fetch-then-enrich pattern; index consumer also uses EnableSecondPasses).
  3. Lock/greylist cleanup still runs via the existing finally in WorkflowConsumer.

Tests

  • QueueConsumerTests.ExecuteItem_ShouldClearSecondPasses_AfterProcessing: duplicate in-flight item is tracked in _secondPasses, then removed after execute.
  • WorkflowConsumerTests.ProcessItem_WhenWorkflowInstanceIsNull_DoesNotThrow: missing instance does not NRE; executor is not called; greylist and lock are still released.

Breaking change
No. Missing instances are now skipped instead of throwing.

Additional context
This does not change how completed workflows are deleted. It only makes consumers tolerant of a queue item whose instance is already gone, and stops leftover second-pass ids from sticking around after execute.

Open in Web Open in Cursor 

cursoragent and others added 2 commits September 8, 2026 00:43
Clear QueueConsumer _secondPasses when an item finishes so completed
or purged workflows are not reprocessed. Skip WorkflowConsumer and
IndexConsumer processing when GetWorkflowInstance returns null, which
happens with Redis deleteCompleted and after WorkflowPurger cleanup.

Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>
Co-authored-by: Daniel Gerlag <danielgerlag@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/fix-stale-second-passes-null-workflow-a70f branch from ce2f6b9 to d4e4440 Compare September 8, 2026 00:43
@cursor

cursor Bot commented Sep 8, 2026

Copy link
Copy Markdown

Rebased onto current master after #1445 (Elasticsearch fixture hardening) so this PR includes that fix. No conflicts; the QueueConsumer second-pass and null-workflow NRE changes are unchanged.

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

Labels

None yet

Projects

None yet

2 participants