fix: report HTTP 404 as endpoint-not-found instead of "malformed event"#74
Merged
colombod merged 2 commits intoJul 15, 2026
Merged
Conversation
The message layer's catch-all else hardcoded "malformed event, skipped" for every
non-retryable (_PERMANENT) HTTP status, so a 404 from an undeployed/misrouted
team-shared server (route missing behind APIM) was reported as if the event payload
were malformed.
Inverted the polarity: "malformed event" is now asserted ONLY for the genuine
payload set {400, 413, 422}; added a dedicated 404/410 branch ("endpoint not
found — verify the route is deployed/reachable behind the gateway; not a payload
problem") with a distinct `endpoint_not_found` forwarding issue-code; and made the
final else cause-neutral ("rejected event (HTTP N) — skipped") so un-enumerated
statuses (405, 409, 451, ...) no longer get a false "malformed" cause.
Corrected three stale docstrings that described _PERMANENT 4xx as "malformed or
forbidden". No change to _classify_http_outcome, retry logic, or the circuit
breaker.
Added parametrized tests: 404/410 -> "endpoint not found" & not "malformed";
400/413/422 -> still "malformed" (regression anchor); 405 -> cause-neutral;
403/3xx unchanged.
Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
uv.lock was pinned to a stale git-dependency commit (an ancestor of current HEAD), causing an ImportError that failed the entire test suite on a clean checkout. Reproduced on the pre-fix tree, so this is pre-existing and independent of the 404 fix. Bumped via `uv lock --upgrade-package` + `uv sync` to unblock testing. Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
colombod
deleted the
fix/404-endpoint-not-found-misclassified-as-malformed
branch
July 15, 2026 15:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When the team-shared Context Intelligence destination server is not deployed (route missing behind APIM), the client POSTs an event and receives HTTP 404. The error message incorrectly reports this as "malformed event, skipped" — blaming the payload when the real cause is an endpoint that doesn't exist.
The message layer's catch-all
elsehardcoded "malformed event, skipped" for every non-retryable (_PERMANENT) HTTP status. This conflated two unrelated problems: a 404 (endpoint not found) and genuine payload validation errors (400/413/422).Fix: Inverted the polarity:
No change to
_classify_http_outcome, retry logic, or the circuit breaker — only the message layer and three stale docstrings.Verification
Unit tests:
ruff formatandruff checkcleanpyrighthas only one pre-existing unrelated error intest_mount_dispatcher.py(untouched by this change)Live endpoint probing:
/eventsroute is not deployedKnown scope & parked follow-ups
_classify_http_outcome(retry decision) and the message layer (user-facing text). This is a candidate for a deliberate, separately-scoped consolidation work, but is not a blocker for fixing the 404 label.Commits
uv.lockgit-dependency pin (reproduced on pre-fix tree, independent of the 404 fix)