fix(db): alias agent_ownership in agent-count subquery to fix auth-report 500 (#1199) - #1204
Merged
Merged
Conversation
…orrelation 500 (#1199) `_agent_count_subquery()` built a scalar subquery whose only FROM was `agent_ownership`, correlated to the outer query on `agent_ownership.subscription_id == subscription_credentials.id`. That is safe in callers whose outer FROM is just `subscription_credentials JOIN users`, but `get_agent_subscription` *also* joins `agent_ownership` in its outer query (to filter by agent_name). SQLAlchemy then auto-correlated `agent_ownership` out of the subquery too, leaving it with no FROM clause and raising `InvalidRequestError` at statement-compile time — so `GET /api/ops/auth-report` (and per-agent subscription-status lookups) 500'd on every call, on both SQLite and PostgreSQL. Alias `agent_ownership` as `ao_count` inside the subquery so its FROM table is always distinct from any outer `agent_ownership`; auto-correlation now only removes `subscription_credentials` (the intended correlation). One-point fix in the shared helper keeps it safe in every caller. Adds tests/unit/test_1199_agent_subscription_correlation.py (backend-agnostic via db_harness — SQLite + Postgres): asserts get_agent_subscription compiles and returns the right row + agent_count, that the deleted_at filter is preserved through the alias, the no-subscription contract is unchanged, and the sibling callers still compile. Pre-fix the get_agent_subscription cases fail with the exact "returned no FROM clauses due to auto-correlation" error. Fixes #1199 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
GET /api/ops/auth-report(and per-agent subscription-status lookups) 500'd on every call on v0.6.1 withsqlalchemy.exc.InvalidRequestError: ... returned no FROM clauses due to auto-correlation.SubscriptionOperations._agent_count_subquery()builds a scalar subquery whose only FROM isagent_ownership, correlated onagent_ownership.subscription_id == subscription_credentials.id.get_agent_subscriptionalso joinsagent_ownershipin its outer query, so SQLAlchemy auto-correlatesagent_ownershipout of the subquery too — leaving it FROM-less and failing at statement-compile time (so it 500s regardless of data, on both SQLite and PostgreSQL).agent_ownershipasao_countinside the subquery so its FROM is always distinct from any outeragent_ownership. Auto-correlation now only removessubscription_credentials(the intended correlation). One-point fix in the shared helper → safe in every caller.Changes
src/backend/db/subscriptions.py— aliasagent_ownership(ao_count) inside_agent_count_subquery()+ explanatory docstring.tests/unit/test_1199_agent_subscription_correlation.py— new backend-agnostic regression tests (db_harness, SQLite + Postgres).Why the alias (not
.correlate())The alias makes the helper correct in all callers, including any future one that joins
agent_ownershipin its outer FROM — the issue's recommended, most-robust option. The four existing callers without anagent_ownershipouter join (get_subscription,list_subscriptions,get_least_used_subscription,select_best_alternative_subscription) are unaffected (covered by the sibling-compile test).Test Plan
get_agent_subscriptioncases fail with the exactInvalidRequestError: returned no FROM clauses due to auto-correlation(verified by reverting the source fix in isolation).agent_count,deleted_at IS NULLfilter preserved through the alias, no-subscription contract unchanged, sibling callers still compile.test_1199_*,test_subscription_auto_switch_*,test_inject_assigned_credentials,test_subscription_bola).cd tests && python -m pytest unit/test_1199_agent_subscription_correlation.py -vDocs
None — bug-fix tier (commit message only). No feature flow / architecture change: the endpoint, call, and
agent_countshape are unchanged; the fix restores the behaviorsubscription-management.mdalready documents.Fixes #1199
🤖 Generated with Claude Code