bugfix: issue-191 strict model routing bypass#197
Conversation
…es so rejections fail fast consistently (#191)
Rewrites TestResolveAliasEndpoints_NoMatchingEndpoints to assert the fixed empty-result behaviour instead of the old assert.Len(result,1) that codified the bug, adds strict_strategy_test.go covering the three routing outcomes (routed/rejected-503/rejected-404), and adds a full-handler httptest covering both providerProxyHandler and proxyHandler with a real inspector chain to prove a rejected alias never reaches the proxy engine. Also adds a guarded, documented e2e case to test-model-routing-strategy.sh (needs a live Olla with model_aliases + strict routing configured; not runnable in this environment).
…d action string (#191)
…endpoint rejection (#191)
WalkthroughUnroutable model aliases now fail fast under strict routing instead of reaching compatible backends. Shared proxy and translation paths preserve routing decisions, statuses, headers, sticky-session data, and rejection logs, with unit, regression, documentation, and script coverage. ChangesStrict alias routing
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/app/handlers/handler_proxy.go`:
- Around line 719-727: Update the alias no-candidate branch near
profile.RoutingDecision to consult the configured routing strategy and
fallback_behavior before rejecting. Preserve the healthy fallback path for
optimistic with fallback_behavior set to all, and only create the
model_unavailable rejected decision and return an empty endpoint list when the
active policy disallows fallback.
In `@test/scripts/logic/test-model-routing-strategy.sh`:
- Around line 91-101: Update the rejection check in the response-validation
block to require both status_code 404/503 and a decision_header containing
“X-Olla-Routing-Decision: rejected”; otherwise increment the script’s failure
counter or return a non-zero status so a proxied 200 fails the regression test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9352dcf7-c2fc-48c3-8ec8-de1816030b84
📒 Files selected for processing (11)
docs/content/concepts/model-aliases.mddocs/content/configuration/reference.mdinternal/adapter/registry/routing/strict_strategy_test.gointernal/app/handlers/handler_provider_common.gointernal/app/handlers/handler_proxy.gointernal/app/handlers/handler_proxy_alias_strict_test.gointernal/app/handlers/handler_proxy_alias_test.gointernal/app/handlers/handler_proxy_model_test.gointernal/app/handlers/handler_translation.gointernal/app/handlers/handler_translation_strict_rejection_test.gotest/scripts/logic/test-model-routing-strategy.sh
There was a problem hiding this comment.
🧹 Nitpick comments (2)
internal/app/handlers/handler_proxy_alias_test.go (2)
258-266: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSimplify the test documentation.
The comment explains what changed alongside PR history and uses spaced hyphens as em-dashes. As per coding guidelines, "Comment on why, not what. Concise and direct." and "No em-dashes."
♻️ Proposed refactor
-// TestResolveAliasEndpoints_NoIntersectionWithCandidates_OptimisticFallsBack covers the -// other side of the same fix: under a registry that returns a fallback decision with -// endpoints (optimistic routing, fallback_behavior: all) instead of a rejection, the -// no-intersection branch must let that fallback through rather than unconditionally -// returning empty. This is the behaviour CodeRabbit flagged as missing - previously this -// branch always rejected, so optimistic/all could never recover here. The returned -// endpoints don't serve the alias's actual target models (they're the routing strategy's -// substitute, not an alias match), so the alias rewrite map must NOT be set - the proxy -// has to forward the original request body unchanged. +// TestResolveAliasEndpoints_NoIntersectionWithCandidates_OptimisticFallsBack ensures that optimistic +// routing allows fallback when an alias has no compatible candidates. The fallback endpoints +// are substitutes rather than direct matches, so the alias rewrite map must not be set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/app/handlers/handler_proxy_alias_test.go` around lines 258 - 266, Condense the comment above TestResolveAliasEndpoints_NoIntersectionWithCandidates_OptimisticFallsBack to state only why the no-intersection case must allow optimistic fallback endpoints through without setting the alias rewrite map. Remove PR history, implementation narration, and spaced-hyphen em-dash phrasing.Source: Coding guidelines
196-204: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSimplify the test documentation.
The comment explains what changed by detailing its PR history and uses spaced hyphens as em-dashes. As per coding guidelines, "Comment on why, not what. Concise and direct." and "No em-dashes."
♻️ Proposed refactor
-// TestResolveAliasEndpoints_NoIntersectionWithCandidates_StrictRejects covers fix 4 from -// the `#191` follow-up review, CodeRabbit round 2: the alias resolves to real target models, -// but none of the endpoints serving those models are in the healthy/compatible candidate -// list. Rather than the handler synthesising its own rejection, this must fall through to -// the configured routing strategy for the alias name itself - exactly like the "resolved to -// no endpoints at all" branch - so the strategy's decision (not a hardcoded one) governs the -// outcome. Under a strict/rejecting registry that decision is still a fail-fast rejection, -// just reported as model_not_found/404 (an unknown model name) rather than the -// alias-specific model_unavailable/503 the handler used to synthesise. +// TestResolveAliasEndpoints_NoIntersectionWithCandidates_StrictRejects ensures that when an alias +// has no compatible endpoints, it falls back to the routing strategy's decision. Under a +// strict registry, this correctly yields a 404 rejection instead of a hardcoded 503.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/app/handlers/handler_proxy_alias_test.go` around lines 196 - 204, Simplify the documentation comment for TestResolveAliasEndpoints_NoIntersectionWithCandidates_StrictRejects by removing PR/review history and implementation-detail narration. Briefly state the behavior being verified: when no candidate endpoint serves the resolved alias targets, routing falls back to the alias strategy and strict rejection returns model_not_found/404. Use direct punctuation without em-dashes.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@internal/app/handlers/handler_proxy_alias_test.go`:
- Around line 258-266: Condense the comment above
TestResolveAliasEndpoints_NoIntersectionWithCandidates_OptimisticFallsBack to
state only why the no-intersection case must allow optimistic fallback endpoints
through without setting the alias rewrite map. Remove PR history, implementation
narration, and spaced-hyphen em-dash phrasing.
- Around line 196-204: Simplify the documentation comment for
TestResolveAliasEndpoints_NoIntersectionWithCandidates_StrictRejects by removing
PR/review history and implementation-detail narration. Briefly state the
behavior being verified: when no candidate endpoint serves the resolved alias
targets, routing falls back to the alias strategy and strict rejection returns
model_not_found/404. Use direct punctuation without em-dashes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a0e7f393-5dfd-41da-b85c-bfa6db212149
📒 Files selected for processing (3)
internal/app/handlers/handler_proxy.gointernal/app/handlers/handler_proxy_alias_test.gotest/scripts/logic/test-model-routing-strategy.sh
🚧 Files skipped from review as they are similar to previous changes (2)
- test/scripts/logic/test-model-routing-strategy.sh
- internal/app/handlers/handler_proxy.go
Strict routing could be bypassed when a request used a model_aliases entry whose target model existed on no endpoint: the routing decision was logged as rejected, but the request was still proxied to a compatible backend and returned 200. Requests now fail fast with a decision-aware 404/503 and routing_action: rejected, matching how unknown models are already handled.
This resolves #191
Changes
Behavioural notes
/olla/proxy/with zero healthy endpoints now returns 503 (previously 502 from the proxy engine); adjust any monitors keyed on 502 which most folks won't have we think.Summary by CodeRabbit
Bug Fixes
Documentation
Tests