Skip to content

fix(queue): carry the target namespace from enqueue through to delivery - #622

Open
anthonyiscoding wants to merge 1 commit into
feat/new-sdk-migrationfrom
fix/queue-namespace-propagation
Open

fix(queue): carry the target namespace from enqueue through to delivery#622
anthonyiscoding wants to merge 1 commit into
feat/new-sdk-migrationfrom
fix/queue-namespace-propagation

Conversation

@anthonyiscoding

Copy link
Copy Markdown
Contributor

Problem

An enqueue addressed to a namespace never reached its handler. smoke-tests/ns_queue_dispatch — a worker in jobs registers task::run, the driver enqueues an invocation addressed to jobs — was silently reporting SKIP: no enqueue provider even with the queue worker running and engine::queue::enqueue registered.

The engine was doing the right thing throughout: it sends the target namespace to the enqueue provider and resolves that provider fine. The worker dropped the namespace in three places.

Fixes

  1. Rejected the field outright. EnqueueInput is #[serde(deny_unknown_fields)] and had no namespace, so every namespaced enqueue failed with unknown field 'namespace', expected one of queue, function_id, data, messageReceiptId, traceparent, baggage, _caller_worker_id. The scenario's SKIP branch matches any error containing "enqueue", which is what disguised this as a missing worker.
  2. Didn't persist it. A namespace that isn't stored can't survive a restart. Added to the builtin adapter's on-disk envelope (#[serde(default)], so jobs written by older workers still deserialize), the RabbitMQ AMQP headers on both publish and consume, the redis envelope, and QueueMessage.
  3. Didn't address it on delivery. Invoker was namespace-blind, so deliveries landed in the worker's own namespace. Added call_in_namespace, defaulting to the existing namespace-blind call_with_timeout so the test and embedded invokers need no plumbing, and overrode it in IiiInvoker to target the namespace via the SDK's TriggerRequest::namespace().

function_available needed no change — engine::functions::info already resolves a bare function_id across namespaces and reports the namespace it found.

Testing

  • Worker suite: 130 tests, 0 failures, including the RabbitMQ e2e tests.
  • ns_queue_dispatch: SKIP → 2/2 passed in python, node, and rust.
  • upgrade_queue_builtin_drain, upgrade_queue_rabbitmq_breaking, upgrade_state_survives: still green.

Notes for review

  • publish_to_function_queue is now 11 positional parameters. It was already over the line at 10 (hence the #[allow(clippy::too_many_arguments)]); I added the parameter rather than widen the diff into a signature refactor, but bundling these into a FunctionJob struct would be a good follow-up.
  • The redis adapter publishes the namespace but has no function-queue consume path to read it back, so redis deliveries are unchanged for now.
  • Separately worth doing in smoke-tests: narrow that SKIP branch to a genuine provider-not-found check, so the next contract break fails loudly instead of skipping.

🤖 Generated with Claude Code

An enqueue addressed to a namespace failed outright and, once accepted,
was delivered to the wrong namespace. Three separate drops:

- `EnqueueInput` is `deny_unknown_fields` and had no `namespace`, so the
  namespace the engine sends made every namespaced enqueue fail with
  `unknown field 'namespace'`.
- The job did not persist the namespace, so it could not survive a
  restart: added to the builtin on-disk envelope (`serde(default)`, so
  jobs written by older workers still deserialize), the RabbitMQ headers
  on publish and consume, the redis envelope, and `QueueMessage`.
- `Invoker` was namespace-blind, so deliveries always landed in the
  worker's own namespace. Added `call_in_namespace`, defaulting to the
  existing namespace-blind call so test and embedded invokers are
  unaffected, and overrode it in `IiiInvoker` to address the target via
  the SDK's `TriggerRequest::namespace()`.

`function_available` needs no change: `engine::functions::info` already
resolves a bare `function_id` across namespaces.

Verified with the full worker suite (130 tests, including the RabbitMQ
e2e tests) and the smoke-tests `ns_queue_dispatch` scenario, which went
from SKIP to 2/2 in python, node, and rust; `upgrade_queue_builtin_drain`
and `upgrade_queue_rabbitmq_breaking` stay green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview, Comment Jul 29, 2026 3:08pm
workers-tech-spec Ready Ready Preview, Comment Jul 29, 2026 3:08pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5cbe2f53-e9eb-4aa7-a5ba-a08a5d14fa69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 49 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

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