Skip to content

fix: dead-letter parse and handler failures; add DLQ binding#10

Merged
jorisjonkers-dev-agents[bot] merged 3 commits into
mainfrom
fix/dlx-dlq-ingest-worker
Jul 10, 2026
Merged

fix: dead-letter parse and handler failures; add DLQ binding#10
jorisjonkers-dev-agents[bot] merged 3 commits into
mainfrom
fix/dlx-dlq-ingest-worker

Conversation

@jorisjonkers-dev-agents

Copy link
Copy Markdown
Contributor

Fixes #9

Changes

consumer.py — Parse failures (ValidationError, json.JSONDecodeError, UnicodeDecodeError) were previously basic_ack'd, causing silent data loss. They are now basic_nack(requeue=False) so the broker routes the poison payload to knowledge.ingest.dlq via the DLX. Handler failures were already nacked but shared the same missing-binding problem.

IngestQueueConfig.kt — The DLQ queue existed but there was no binding from knowledge.dlx to it. Added the missing Binding bean. Changed the DLX declaration from TopicExchange to FanoutExchange so any nacked delivery from the ingest queue lands on the DLQ regardless of routing key.

Integration test — New test_malformed_payload_routes_to_dlq test spins up a real RabbitMQ container via Testcontainers, declares the full DLX topology, publishes a malformed payload, and asserts the body appears on the DLQ (not silently dropped).

Unit tests — Two tests that asserted basic_ack on parse failures are corrected to assert basic_nack(requeue=False).

Docsingest-worker/README.md and knowledge_worker/__main__.py docstring updated to reflect the wired VaultHandler behaviour and the error-handling contract.

Out of scope

MCP API gaps (link_note/link_notes, project-vocabulary tools) noted in the issue are a feature addition beyond this bug fix.

…ing (#9)

Parse failures in consumer.py were ACK'd (silent data loss). Handler
failures were already nacked but the DLQ binding on knowledge.dlx was
missing, so messages vanished. This change:

- Switches parse failure path from basic_ack to basic_nack(requeue=False)
  so poison payloads route to knowledge.ingest.dlq via the DLX
- Adds the missing Binding bean in IngestQueueConfig (knowledge.dlx →
  knowledge.ingest.dlq) and changes the DLX to FanoutExchange
- Adds a Testcontainers integration test asserting malformed payloads
  land on the DLQ rather than disappearing
- Updates unit tests to assert nack (not ack) on parse failures
- Updates stale skeleton docs in README.md and __main__.py docstring

MCP API gaps (link_note / project-vocabulary tools) are out of scope
for this fix and tracked separately on the issue.
@jorisjonkers-dev-agents jorisjonkers-dev-agents Bot added the type: bug Something is broken or behaving incorrectly. label Jul 10, 2026
…ng broker

Per codex review: switching knowledge.dlx from TopicExchange to FanoutExchange
would cause PRECONDITION_FAILED on any broker that already has it declared.
Retain TopicExchange and bind the DLQ with routing key knowledge.ingest.dlq
(which the main queue already stamps as x-dead-letter-routing-key). Update
the integration test topology to match.
@jorisjonkers-dev-agents jorisjonkers-dev-agents Bot merged commit d0b715f into main Jul 10, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug Something is broken or behaving incorrectly.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ingest-worker DLQ for malformed payloads + stale skeleton docs + MCP API gaps for council (link_note, project vocab)

1 participant