Skip to content

fix(db): alias agent_ownership in agent-count subquery to fix auth-report 500 (#1199) - #1204

Merged
vybe merged 1 commit into
devfrom
feature/1199-subscription-correlation
Jun 14, 2026
Merged

fix(db): alias agent_ownership in agent-count subquery to fix auth-report 500 (#1199)#1204
vybe merged 1 commit into
devfrom
feature/1199-subscription-correlation

Conversation

@vybe

@vybe vybe commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • GET /api/ops/auth-report (and per-agent subscription-status lookups) 500'd on every call on v0.6.1 with sqlalchemy.exc.InvalidRequestError: ... returned no FROM clauses due to auto-correlation.
  • Root cause: SubscriptionOperations._agent_count_subquery() builds a scalar subquery whose only FROM is agent_ownership, correlated on agent_ownership.subscription_id == subscription_credentials.id. get_agent_subscription also joins agent_ownership in its outer query, so SQLAlchemy auto-correlates agent_ownership out 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).
  • Fix: alias agent_ownership as ao_count inside the subquery so its FROM 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 → safe in every caller.

Changes

  • src/backend/db/subscriptions.py — alias agent_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_ownership in its outer FROM — the issue's recommended, most-robust option. The four existing callers without an agent_ownership outer join (get_subscription, list_subscriptions, get_least_used_subscription, select_best_alternative_subscription) are unaffected (covered by the sibling-compile test).

Test Plan

  • Pre-fix: the 3 get_agent_subscription cases fail with the exact InvalidRequestError: returned no FROM clauses due to auto-correlation (verified by reverting the source fix in isolation).
  • Post-fix: all 4 new cases pass — statement compiles, returns the right row + agent_count, deleted_at IS NULL filter preserved through the alias, no-subscription contract unchanged, sibling callers still compile.
  • No regressions: 37 subscription unit tests pass (test_1199_*, test_subscription_auto_switch_*, test_inject_assigned_credentials, test_subscription_bola).
  • Run: cd tests && python -m pytest unit/test_1199_agent_subscription_correlation.py -v

Docs

None — bug-fix tier (commit message only). No feature flow / architecture change: the endpoint, call, and agent_count shape are unchanged; the fix restores the behavior subscription-management.md already documents.

Fixes #1199

🤖 Generated with Claude Code

…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>
@vybe
vybe merged commit fcfb93a into dev Jun 14, 2026
13 of 15 checks passed
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