fix(cli): honor SUPABASE_API_* overrides (CLI-2318) - #6467
Conversation
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
The API override fold is broadly correct, but five concerns are confirmed: port zero bypasses required-port validation; malformed API overrides are skipped by the empty-config path; dotenv-only auth overrides remain ignored by some local callers; one test can leak ambient state if setup throws; and one assertion is unnecessarily indirect. The alleged per-command test-coverage violation is refuted because the changed behavior is centralized and exercised through the shared resolver.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟡 MINOR | apps/cli/src/legacy/shared/legacy-storage-credentials.ts:174 |
validation |
claude+codex | SUPABASE_API_PORT=0 is accepted and can produce a gateway URL using port zero even though enabled API configurations require a nonzero port. |
| 🟡 MINOR | apps/cli/src/legacy/shared/legacy-seed-buckets.ts:241 |
validation-order |
claude | Malformed SUPABASE_API_PORT or SUPABASE_API_*_ENABLED values are not validated when a local seed-buckets run takes the empty-config short circuit. |
| 🟡 MINOR | apps/cli/src/legacy/shared/legacy-storage-credentials.ts:221 |
configuration-consistency |
claude | Dotenv-only SUPABASE_AUTH_JWT_SECRET and SUPABASE_AUTH_SERVICE_ROLE_KEY values remain invisible to local storage credential resolution even though the function now loads the project dotenv map. |
| ⚪ NIT | apps/cli/src/legacy/commands/seed/buckets/buckets.integration.test.ts:1067 |
test-hygiene |
claude | The ambient SUPABASE_API_PORT mutation can leak into later tests if synchronous test setup throws before the Effect finalizer is constructed. |
| ⚪ NIT | apps/cli/src/legacy/commands/seed/buckets/buckets.integration.test.ts:1080 |
readability |
claude | The request-port assertion indirectly compares two mapped arrays instead of directly asserting that every request used the expected port. |
Findings outside the diff
- 🟡 MINOR
apps/cli/src/legacy/shared/legacy-seed-buckets.ts:241— Malformed SUPABASE_API_PORT or SUPABASE_API_*_ENABLED values are not validated when a local seed-buckets run takes the empty-config short circuit. - 🟡 MINOR
apps/cli/src/legacy/shared/legacy-storage-credentials.ts:221— Dotenv-only SUPABASE_AUTH_JWT_SECRET and SUPABASE_AUTH_SERVICE_ROLE_KEY values remain invisible to local storage credential resolution even though the function now loads the project dotenv map.
Refuted findings (kept for transparency, not posted as review comments)
apps/cli/src/legacy/commands/storage/ls/SIDE_EFFECTS.md:13(test-coverage): The storage commands and db reset require separate integration tests for the newly documented API dotenv behavior.
Refuted: The production behavior is centralized in legacyResolveStorageCredentials, called by both legacy-seed-buckets.ts:249 and storage.frame.ts:92-95. The added seed-buckets integration cases exercise that shared resolver, and trusted/apps/cli/CLAUDE.md:277-279 requires tests and SIDE_EFFECTS documentation to be updated together but does not require duplicate tests for every unchanged caller.
Stats
Claude findings: 6 · Codex findings: 1 · Confirmed: 5 · Refuted: 1 · Uncertain: 0
Models: claude-opus-5 + gpt-5.6-sol · Trigger: auto · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@ea4123bbe49d3781ca3a9727e4fbe79dc9fce939Preview package for commit |
Coly010
left a comment
There was a problem hiding this comment.
Verified the core fix: resolveLocalApiConfig's zero-port gate matches legacyValidateResolvedConfig's message/ordering exactly, and the override-precedence semantics line up with start/status/stop. Test coverage in buckets.integration.test.ts is thorough (port, external_url, TLS enable/cert/key, malformed values, zero-port enabled/disabled). Left inline notes on the items below; two more that fall outside this diff's changed files:
legacy-seed-buckets.ts's empty-config short-circuit (around theif (projectRef === "" && bucketNames.length === 0 && !hasVectorBuckets)check) returns beforelegacyResolveStorageCredentialsever runs, so a malformedSUPABASE_API_PORT/zero-port-while-enabled override silently exits 0 when there's nothing configured to seed. Low real-world impact (nothing observable happens either way) — noting for awareness, not blocking.- Consider filing a follow-up issue for the
resolveLocalServiceRoleKeydotenv blind spot noted inline below — same root cause class as this fix (#6452), but the vault-decryption path involved makes it more than a one-line change, so it's reasonable to scope it out of this PR.
Nice fix overall — thanks for tracking down #6452.
|
/ai-review |
There was a problem hiding this comment.
🤖 AI Review
Both independent reviews completed. Six findings are confirmed: two minor correctness issues and four test/performance nits. Two findings are refuted because current callers enforce local-only config loading and the allegedly omitted test variable cannot affect the tested validations. No critical or major issues were verified.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟡 MINOR | apps/cli/src/legacy/shared/legacy-storage-credentials.ts:128 |
correctness |
claude | Local service-role credential resolution ignores SUPABASE_AUTH_JWT_SECRET and SUPABASE_AUTH_SERVICE_ROLE_KEY values supplied only through project dotenv files. |
| 🟡 MINOR | apps/cli/src/legacy/shared/legacy-seed-buckets.ts:255 |
correctness |
codex | Malformed local API overrides are not validated when bucket seeding takes the empty-config short circuit. |
| ⚪ NIT | apps/cli/src/legacy/commands/seed/buckets/buckets.integration.test.ts:1091 |
test-hermeticity |
claude | The new dotenv-driven API override tests do not clear ambient SUPABASE_API_* variables, allowing host environment values to shadow their fixtures. |
| ⚪ NIT | apps/cli/src/legacy/commands/seed/buckets/buckets.integration.test.ts:1262 |
test-quality |
claude | Two success-path tests use requests.every(...) without asserting that any request occurred. |
| ⚪ NIT | apps/cli/src/legacy/commands/seed/buckets/buckets.integration.test.ts:1144 |
test-quality |
codex | The new failure tests inspect Effect's serialized runtime representation rather than extracting typed failures through public helpers. |
| ⚪ NIT | apps/cli/src/legacy/commands/storage/rm/rm.handler.ts:90 |
performance |
claude | storage rm --local walks the project dotenv files twice. |
Findings outside the diff
- ⚪ NIT
apps/cli/src/legacy/commands/storage/rm/rm.handler.ts:90— storage rm --local walks the project dotenv files twice.
Refuted findings (kept for transparency, not posted as review comments)
apps/cli/src/legacy/shared/legacy-storage-credentials.ts:171(correctness): resolveLocalApiConfig applies SUPABASE_API_* overrides without remote-over-environment precedence, relying on callers to supply an unmerged local config.
Refuted: Every current local caller supplies config loaded without a projectRef, while remote callers bypass resolveLocalApiConfig. The claimed precedence failure therefore has no reachable execution path; it depends on hypothetical future misuse already documented at lines 167-169.apps/cli/src/legacy/shared/legacy-config-validate.parity.unit.test.ts:332(test-quality): The isolated helper says it unsets every participating key but omits SUPABASE_API_EXTERNAL_URL.
Refuted: SUPABASE_API_EXTERNAL_URL cannot affect either tested outcome: API-port validation occurs inside resolveLocalApiConfig at line 209, and TLS presence validation depends only on enabled/cert/key fields at lines 137-144. It therefore does not participate in these assertions.
Stats
Claude findings: 6 · Codex findings: 2 · Confirmed: 6 · Refuted: 2 · Uncertain: 0
Models: claude-opus-5 + gpt-5.6-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
TL;DR
fixes
seed buckets,db reset, andstorage --localignoring theSUPABASE_API_*overrides and calling the local storage gateway on the rawconfig.tomlport...whats broken?
SUPABASE_API_PORT=54331 supabase seed bucketsfails with a transport error onhttp://127.0.0.1:54321/storage/v1/bucketthe shared credentials resolver reads
api.port,api.external_url, andapi.tls.*raw, whilestart/status/stopresolve the same fields post-override. the CLI can start a stack it then cannot reach.now fixed by:
folding the
SUPABASE_API_*overrides once inresolveLocalApiConfigthru the same
legacyEnvOverride*helpers and dotenv walk the sibling commands useso the gateway URL and TLS gate read the resolved view. a malformed override now fails with the same invalid config error
start/status/stopalready raise.--linkeduntouched...ref: