Skip to content

fix: report HTTP 404 as endpoint-not-found instead of "malformed event"#74

Merged
colombod merged 2 commits into
mainfrom
fix/404-endpoint-not-found-misclassified-as-malformed
Jul 15, 2026
Merged

fix: report HTTP 404 as endpoint-not-found instead of "malformed event"#74
colombod merged 2 commits into
mainfrom
fix/404-endpoint-not-found-misclassified-as-malformed

Conversation

@colombod

Copy link
Copy Markdown
Collaborator

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 else hardcoded "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:

  • "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 and reachable behind the gateway; not a payload problem"
  • Made the final catch-all cause-neutral ("rejected event (HTTP N) — skipped") so un-enumerated statuses (405, 409, 451, ...) no longer inherit a false "malformed" cause

No change to _classify_http_outcome, retry logic, or the circuit breaker — only the message layer and three stale docstrings.

Verification

Unit tests:

  • Target files: 69 passed (5 new parametrized cases: 404/410 → "endpoint not found" + NOT "malformed"; 400/413/422 → still "malformed" regression anchor; 405 → cause-neutral; 403/3xx regression anchors)
  • Full module suite: 576 passed
  • Lint/format: ruff format and ruff check clean
  • Type checking: pyright has only one pre-existing unrelated error in test_mount_dispatcher.py (untouched by this change)

Live endpoint probing:

  • Hitting the actual team-shared server returns HTTP 401 (APIM auth-gates before route resolution)
  • The reported 404 requires a correctly-authenticated client whose backend /events route is not deployed
  • The 404→message mapping is therefore unit-verified; the actual 404 path is not independently reproduced (requires CI-app-scoped credential)

Known scope & parked follow-ups

  1. 401 auth-failure handling: The 401 path is a separate behavior that deserves its own review and potential fix in retry/backoff strategy — out of scope for this change.
  2. Consolidated status meaning: HTTP status classification lives in two places — _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

  1. Commit 1 (2d56efd): Bug fix — handler, tests, docstrings corrected
  2. Commit 2 (6c677c7): Chore — bump pre-existing stale uv.lock git-dependency pin (reproduced on pre-fix tree, independent of the 404 fix)

colombod and others added 2 commits July 15, 2026 15:17
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
colombod merged commit baca654 into main Jul 15, 2026
8 checks passed
@colombod
colombod deleted the fix/404-endpoint-not-found-misclassified-as-malformed branch July 15, 2026 15:31
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