Skip to content

fix(worker): pass DeferOperation through MemoryEngine.execute_task#1135

Merged
nicoloboschi merged 1 commit intomainfrom
fix/memory-engine-defer-passthrough
Apr 20, 2026
Merged

fix(worker): pass DeferOperation through MemoryEngine.execute_task#1135
nicoloboschi merged 1 commit intomainfrom
fix/memory-engine-defer-passthrough

Conversation

@cdbartholomew
Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1105. The poller catches DeferOperation and routes it to
_defer_operation (no retry_count bump, no error_message), but the
outer MemoryEngine.execute_task dispatcher has a broad
except Exception that converts every exception — including
DeferOperation — into a RetryTaskAt(60s).

Net effect: a task deferred hours out (e.g. by a backpressure-aware
validator waiting for a quota window) instead came back in 60 seconds
with retry_count bumped. The "defer is not a failure" semantics from
#1105 were silently lost for any exception raised from inside an
executor.

Fix

One-line addition: except DeferOperation: raise alongside the existing
RetryTaskAt passthrough. Paired import added.

Test plan

  • New regression test test_memory_engine_execute_task_passes_through_defer_operation injects a validator that raises DeferOperation from validate_retain, submits a batch_retain task through MemoryEngine.execute_task, and asserts the exception that escapes is DeferOperation (not RetryTaskAt).
  • ./scripts/hooks/lint.sh clean
  • Existing DeferOperation tests in test_worker.py unaffected (they use a synthetic executor that doesn't exercise the execute_task wrapper)

PR #1105 added DeferOperation support in the worker poller
(poller._execute_task_inner catches it and routes to _defer_operation
without bumping retry_count or writing error_message). The outer
dispatcher in MemoryEngine.execute_task, however, still had a
generic `except Exception` that converted every exception — including
DeferOperation — into a RetryTaskAt(60s).

Result: a task deferred hours out (e.g. by a backpressure-aware
validator raising DeferOperation to wait for a quota window) instead
came back in 60 seconds with retry_count bumped, losing the "defer is
not a failure" semantics.

Fix: add `except DeferOperation: raise` alongside the existing
RetryTaskAt passthrough.

Test: new regression test exercises MemoryEngine.execute_task with a
validator that raises DeferOperation from validate_retain, asserting
the exception escapes intact.
@nicoloboschi nicoloboschi merged commit 858f0b3 into main Apr 20, 2026
54 of 56 checks 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.

2 participants