Repository navigation
chore: production deploy - #7452
supabase-cli-releaser[bot] wants to merge 86 commits into
Conversation
`branches create`, `vanity-subdomains activate`, and `vanity-subdomains check-availability` ran an entitlements lookup (get project, then get organization entitlements) after any 4xx without the `entitlement_required` envelope. The Management API already returns that envelope on all three gates, so the lookup only ran for errors unrelated to the plan: two extra requests, and on an org without the feature, an upgrade hint and a `plan_limit` classification for an unrelated error such as a validation failure. I removed the lookup and its permission declarations at those three commands. The CLI still prints the upgrade hint from the envelope on gated denials and fires `cli_upgrade_suggested` for `branches create` and `vanity-subdomains activate` (`check-availability` still suppresses the event), unchanged since #7271. **Note:** I left `branches update` and the `sso` commands on the lookup for now: the SAML routes return no envelope yet, and I haven't confirmed that the persistent-branch gate on `branches update` returns one. ## Linear - part of GROWTH-1050
## TL;DR fixes `supabase start` sitting about 10s on docker's first health check when the services are already up. ## whats improved/fixed? docker runs a container's first health check one full interval after it starts, and our interval is 10s. so `supabase start` kept waiting on that check even when everything was ready sooner. a restart with the issue's excludes went from about 12.8s to 5.2s. a full stack restart went from about 14s to 8s `db start` and `db reset` get the same. ## how? containers with a docker healthcheck now get `--health-start-interval 1s` and a 10s start period when `docker version` shows API 1.44 or newer for the client binary, the client in use, and the daemon, so the first check runs about 1s in and the interval stays 10s after. kong's check lived only in its image, so its spec now sets the same `kong health` check and gets those flags too. > [!NOTE] > on engines without the flag (docker below API 1.44, podman) containers keep the 10s first check. ## ref: - closes: #7427
) Follow-up to #7412. Block-scoped workloads started one stack per block of five launches, so a ten-run workload gave each build only two stack sessions. Launches in one block share a stack session, so session-to-session spread could push the branch median outside the base range, and an A/A run (same CLI code as base and branch) was flagged as slower or faster. - Blocks are now two launches, so each build gets five stack sessions at ten runs, and each measured launch records its block index in the report. - With at least three paired blocks, the block is the unit of evidence. The median of the per-block deltas must clear the existing 5 percent and 5 ms floor, a strict majority of blocks must move the same way past that floor, and the median delta must exceed 1.5 times the larger interquartile range of the two builds' block medians. One odd block cannot create or hide a verdict, and mixed-sign blocks read as within noise. - Run-scoped workloads keep the existing rule (the branch median outside the base min-max range) and also need the median delta to exceed 1.5 times the larger interquartile range of the two builds' launches, so a wide spread reads as noise. - `estimatedSeconds` for block-scoped workloads is rescaled for the extra stack sessions, and `tracing-monitoring.md` describes the new rule. False positives may not be entirely eliminated. A follow-up could allow re-running one or more chosen workloads, so a reported regression can be confirmed without re-running the whole benchmark. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) The local container inputs precedence goldens recorded the default Postgres image tag, so every Postgres bump PR (e.g. #7408) failed integration tests until the goldens were regenerated by hand. The test now redacts the current default database image as `<DEFAULT_POSTGRES_IMAGE>`, keeping the goldens focused on config precedence. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…7443) The Management API spec now describes the ESZIP update-function body through a shared component that carries a `description` and `contentEncoding`. The generator only rewrote a bare `{ format: "binary" }` annotation to `BinaryInput`, so this body regenerated as `Schema.String` and rejected `Uint8Array`/`ArrayBuffer`/`Blob` uploads (breaking `functions deploy`). The sanitizer now reduces binary string schemas to their type and format, so they keep generating as `BinaryInput`. Generated output on `develop` is unchanged; this unblocks the API sync in #7418, which still needs its v2 PostgREST config fixture updated for the new `db_pool_max_lifetime`/`db_pool_max_idletime` fields. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This bumps postgres from 17.11.0.011-r0 to 17.11.0.016-r0. https://github.com/supabase/slim-services/releases/tag/postgres-17.11.0.016-r0 Planned after supabase/slim-services published 17.11.0.015-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Andrew Valleteau <avallete@users.noreply.github.com>
This PR was automatically created to sync the generated `@supabase/api` package with the latest Management API OpenAPI document. Changes were detected in the upstream OpenAPI documents exposed by `https://api.supabase.com/api/v1-json` and `https://api.supabase.com/api/v2-json`. --------- Co-authored-by: jgoux <1443499+jgoux@users.noreply.github.com> Co-authored-by: avallete <andrew.valleteau@supabase.io> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Andrew Valleteau <avallete@users.noreply.github.com>
This bumps postgres from 17.11.0.016-r0 to 17.11.0.017-r0. https://github.com/supabase/slim-services/releases/tag/postgres-17.11.0.017-r0 Planned after supabase/slim-services published 17.11.0.017-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps postgres from 15.19.0.016-r0 to 15.19.0.017-r0. https://github.com/supabase/slim-services/releases/tag/postgres-15.19.0.017-r0 Planned after supabase/slim-services published 17.11.0.017-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## TL;DR The live branch helper now re-creates a branch once when the platform drops TLS while setting the branch password, the same way it handles a 57P01 database restart. - `apps/cli/src/commands/branches/get/get.live.test.ts › gets a preview branch by name`: `branches create` failed with `400: Failed to update password: Client network socket disconnected before secure TLS connection was established`. This is a transient platform rejection during create, like the 57P01 restart from #7256, but the helper only re-issued the create for 57P01. The helper's transient-rejection matcher now also covers this documented TLS drop, so it runs the same single clear-and-recreate. A second rejection still fails. `create.live` uses the same helper and gets the fix too. ## ref spotted in: - https://github.com/supabase/cli/actions/runs/40170147136/job/121099157809 (develop) - https://github.com/supabase/cli/actions/runs/40170152974/job/121099176450 (main) --- _Generated by [Claude Code](https://claude.ai/code/session_014y76TaNM2eKGdpmiMQXWqu)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
## TL;DR The Realtime, pg-meta and Studio catalog test hung on Podman without saying where. It now fails before the test timeout, naming the service and phase that stalled and that service's output. - `Realtime.integration.test.ts › serves Realtime, pg-meta, and Studio against the owned database`: on Podman, the test hit the 120s test timeout with only the generator start frame as a clue. The test runs four services in sequence (database, Realtime, pg-meta, Studio), each with a recipe, start, readiness and HTTP step, so a stall anywhere looked the same. The cause is still unknown, so this change is a diagnostic. The scoped body now runs under a 110s guard. Each step records its phase, and each recipe's launch output is collected. A stall fails with `CatalogStallError` naming the service and phase in progress (including stop and root cleanup) and the last part of that service's output. ## ref spotted in: - https://github.com/supabase/cli/actions/runs/40530528881/job/122281757547 --- _Generated by [Claude Code](https://claude.ai/code/session_01MBEk1PCdaXDCUPR16M9Ria)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
## TL;DR The native owner-logs test no longer pays a private cold artifact fetch inside its timeout, and a stall now names the step that hung. - `Owner.logs.integration.test.ts › persists native output, serves history and follow, and deletes it on destroy`: the test hit the 30s test timeout while starting native Mailpit. The vitest frame pointed at the `openOwner` helper, not the stalled step. This file kept native artifacts in an OS temp cache (`$TMPDIR/supabase-stack-artifacts`) that no other suite shares, so on a runner without a warm temp dir its first native test fetched Mailpit inside the test timeout (the next native test in the file then took ~12s instead of under 1s). The file now uses the shared test artifact cache (`testArtifactCacheRoot`) like the other stack integration suites. The create, start (artifact preparation), readiness, first-follow and history steps also run under a 25s guard that fails with `NativeMailStallError`, naming the step, the instance id and Mailpit's persisted output, so a remaining stall points at its phase. ## ref spotted in: https://github.com/supabase/cli/actions/runs/41383389524/job/125078843228 (green on the same SHA: https://github.com/supabase/cli/actions/runs/41383048926/job/125077793411) --- _Generated by [Claude Code](https://claude.ai/code/session_01MBEk1LVZyNoX4Zg9Nd5ZMM)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This bumps storage from v1.88.0-r0 to v1.89.1-r0. https://github.com/supabase/slim-services/releases/tag/storage-v1.89.1-r0 Planned after supabase/slim-services published v1.89.1-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## TL;DR re-issues the live `db reset` cleanup once when the platform restarts the database, so one dropped connection can't leave a migration behind for the next file - `db reset` live failed in cleanup with `FATAL: terminating connection due to administrator command (SQLSTATE 57P01)` from the pooler on connect. the cleanup reset never ran, so the test's migration stayed in the shared project's history and the following `db push` live file failed with `Remote migration versions not found`. the `db reset` and `db push` cleanups now go through `resetLiveDatabase`, which re-issues the reset once on a platform database restart (the same rule `branches create` already uses) and names the re-issue when it fails again ## ref - spotted in: [failing job](https://github.com/supabase/cli/actions/runs/41176803525/job/124465943942) [green same SHA](https://github.com/supabase/cli/actions/runs/41015125746) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01MBEk1LFBnaQgPd2VvJLo4X Co-authored-by: Claude <noreply@anthropic.com>
…7288) ## TL;DR Two stack integration tests failed because of runner state, not because of the code under test. - `Network.integration.test.ts › a pinned shared listener keeps its reservation until its last route closes`: on Windows, the bind failed as a foreign port conflict on 1801. The random pinned port landed on a port that a Windows runner service holds, and the static held-port list cannot anticipate every such port. `pinnedPort` now draws again until no listener answers the drawn loopback port and the bind's own vacancy guard (`Ports.probeVacant`) accepts it. This replaces the static list. - `DockerDatabaseStorage.integration.test.ts › round-trips PostgreSQL 15 data with its catalog image`: the pull failed with `toomanyrequests` after all pull retries. GHCR rate-limited the runner for longer than the pull backoff, and the tests had no image mirror, unlike the stack's production wiring. Three changes give the tests the same ECR fallback the stack uses: - The tests' container runtimes and the spawned helper-owner fixture now use `slimImageMirrors`. - The direct engine runs use the reference the runtime resolved. - The test that checks a custom mirror keeps its explicit mirror. ## ref spotted in: - https://github.com/supabase/cli/actions/runs/39757673300/job/119753742485 - https://github.com/supabase/cli/actions/runs/39812209412/job/119941209064 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01XrrxbNdkjLwsEeJJiJvGs8 --------- Co-authored-by: Claude <noreply@anthropic.com>
## TL;DR The Mailpit launch test hung on Podman without saying where. It now fails within its timeout, naming the phase that stalled and Mailpit's output. The detached stall guard it uses is now one shared test helper, `failOnStall`, which the Realtime and native owner-logs tests also use. - `Mail.integration.test.ts › launches the real Mailpit recipe and serves its HTTP endpoint`: on Podman, the test hit the 30s test timeout with no diagnostic. The error frame pointed at `sendTestEmail`, but this test never sends mail, so that frame is misleading. The test waits on start, readiness and a `/readyz` request. Container readiness may wait up to 60s, longer than the test timeout, and the `/readyz` request has no bound. So a stall in any of the three looked the same. The whole test scope now runs under one 25s guard inside the 30s test timeout, and a `Ref` tracks the current phase. The test also collects the recipe's log stream, so a stall fails with `MailStallError` naming the phase and showing Mailpit's output so far. - `packages/stack/tests/stall-guard.ts` adds `failOnStall(duration, onStall)`. It joins the guarded effect from a detached fiber, so the stall error surfaces at the deadline instead of waiting for teardown, and it interrupts the stalled fiber in the background so scoped cleanup still runs. `Mail`, `Realtime` (#7359) and `Owner.logs` (#7434) integration tests now share it instead of carrying three copies; each keeps its own stall message. ## ref spotted in: - https://github.com/supabase/cli/actions/runs/39920135558/job/120303098411 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude <noreply@anthropic.com>
This adds postgres 17.11.0.017-orioledb-r0 as a new release line. https://github.com/supabase/slim-services/releases/tag/postgres-17.11.0.017-orioledb-r0 Planned after supabase/slim-services published 17.11.0.017-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps storage from v1.89.1-r0 to v1.89.2-r0. https://github.com/supabase/slim-services/releases/tag/storage-v1.89.2-r0 Planned after supabase/slim-services published v1.89.2-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps realtime from v2.151.3-r0 to v2.151.4-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.151.4-r0 Planned after supabase/slim-services published v2.151.4-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## TL;DR folds the effect lint into `pnpm lint:check`, so one `.oxlintrc.json` drives editors, agents and CI ## whats introduced? - `.oxlintrc.json` extends the `@effect/tsgo` recommended preset, and `.oxlintrc.effect.json` and the `lint:effect:*` scripts go away - `.github/scripts`, the npm launcher shim, compute stack templates and the generated API contracts move to `ignorePatterns`, so they leave the repo lint entirely - `lint:fix` applies suggestions, and `fix:all` runs knip, lint and format in order so fixes never race ## ref - closes: CLI-2899 & CLI-2407
… (#7394) ## TL;DR adds `SUPABASE_API_MAX_RETRIES` so automation can cap management api retries, where `0` sends each request once. ## whats introduced? the new env var sets the retry count on every management api client the cli builds login and `services` included. `functions deploy` caps its own retry loops at that value and keeps honouring rate limit headers, and a duplicated create still becomes an update even at `0`. an invalid value stops the command before any request, and leaving it unset keeps today's behavior... ```mermaid flowchart TD env["SUPABASE_API_MAX_RETRIES"] --> parse{"CommandSettings.load"} parse -- "unset or empty" --> none["none: today's behaviour"] parse -- "plain digits, e.g. 0 or 2" --> some["some(n)"] parse -- "anything else" --> err["ApiMaxRetriesError, exit 1, 0 requests"] none --> defaults["client retries 5 times, deploy keeps its own loops"] some --> clients["Management API clients: retry.maxRetries = n"] clients --> platform["platform api: projects, secrets, link, ..."] clients --> login["login profile lookup"] clients --> services["services version lookup"] some --> deploy["functions deploy: apiMaxRetries"] deploy --> single["command loops capped, client retries off"] single --> dup["duplicated create still becomes one update"] ``` ## why? the management api client retries retryable failures up to 5 times with no way to change that, so eg: a failing `projects list` sends 6 requests, automation that has to stop on the first failure had no supported way to send each request once.... ## ref - closes: #6958
This bumps realtime from v2.151.4-r0 to v2.151.5-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.151.5-r0 Planned after supabase/slim-services published v2.151.5-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps realtime from v2.151.5-r0 to v2.151.6-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.151.6-r0 Planned after supabase/slim-services published v2.151.6-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps postgres from 17.11.0.017-r0 to 17.11.0.018-r0. https://github.com/supabase/slim-services/releases/tag/postgres-17.11.0.018-r0 Planned after supabase/slim-services published 17.11.0.018-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This adds postgres 17.11.0.018-orioledb-r0 as a new release line. https://github.com/supabase/slim-services/releases/tag/postgres-17.11.0.018-orioledb-r0 Planned after supabase/slim-services published 17.11.0.018-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps postgres from 15.19.0.017-r0 to 15.19.0.018-r0. https://github.com/supabase/slim-services/releases/tag/postgres-15.19.0.018-r0 Planned after supabase/slim-services published 17.11.0.018-orioledb-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## Summary Adds `supabase inspect db toast-sizes` — a new `inspect db` subcommand that lists user tables with TOAST storage, ordered by TOAST size (largest first). ## What changed - `apps/cli/src/commands/inspect/db/toast-sizes/` — 3-file subcommand (query, handler, command) - `apps/cli/docs/supabase/inspect/db-toast-sizes.md` — docs overlay with description and sample output - `apps/cli/src/commands/inspect/db/db.command.ts` — registers the new subcommand - `apps/cli/src/commands/inspect/db/SIDE_EFFECTS.md` — updates active count (13 → 14) and query table - `apps/cli/src/commands/inspect/db/inspect-specs.integration.test.ts` — adds a test case for `toastSizesSpec` ## Why it matters TOAST (The Oversized-Attribute Storage Technique) is PostgreSQL's overflow storage for large values in `TEXT`, `JSONB`, and `bytea` columns. Autovacuum runs on TOAST tables **independently** from the main heap, so dead TOAST chunks accumulate silently. A high TOAST dead-tuple ratio increases I/O and inflates effective database size — but it doesn't appear in the existing `bloat` or `vacuum-stats` commands, which only cover the main heap. This command surfaces: - Heap vs. TOAST size split per table - Live/dead TOAST chunk counts and dead-chunk percentage - Last autovacuum/vacuum timestamps on the TOAST table It's a common source of invisible bloat, especially in tables with large JSONB columns. ## Testing - New integration test case in `inspect-specs.integration.test.ts` (count updated 13 → 14) - Query filters out internal Supabase schemas via the shared `$1` LIKE-escape parameter (consistent with `bloat`, `vacuum-stats`, `index-stats`, `table-stats`, `db-stats`) - Docs overlay at `apps/cli/docs/supabase/inspect/db-toast-sizes.md` follows the same format as existing overlays ## Docs A follow-up PR to `supabase/supabase` will add this command to the [Inspect guide](https://supabase.com/docs/guides/observability/inspect) under the **Disk Storage Analysis** section after this merges. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: avallete <andrew.valleteau@supabase.io>
## TL;DR Adds `supabase inspect db collation-drift`, a read-only check for btree indexes whose collation version no longer matches the version the OS now provides. It lists the affected indexes and prints the remediation workflow (amcheck → `REINDEX INDEX CONCURRENTLY` → `REFRESH VERSION`) with the real object names. Supersedes #6666 by @divyasharma95, whose commits are kept as-is; this branch adds the port to the current inspect runner and the review fixes. ## Why After a glibc or ICU upgrade, btree indexes on text columns can be mis-ordered with no error: queries may miss rows, sort incorrectly, or let duplicates past a unique constraint. Postgres only warns about a version mismatch; it does not say which indexes are affected or in which order to fix them, and refreshing the recorded version before rebuilding hides the problem. ## What changed - New `inspect db collation-drift` command, sharing target selection, permissions and connection resolution with the other `inspect db` commands. - Detects drift for the database default collation (PG15+) and for named ICU and libc collations; on PG14 and earlier only named collations are checked. - Lists each affected index once, constraint-backing indexes first, and skips partitioned parent indexes in favour of their partitions. - Text output is a structured report: header, warning, table, and three ordered remediation steps. `--output-format json` emits `{ rows, report }`, keeping the `rows` shape of the other inspect commands. - Introduces a small `Report` document model (`apps/cli/src/output/report.types.ts`) and its text renderer, used only by this command for now. Known limitation: expression indexes (for example `lower(name)`) are not detected; the remediation text tells users to rebuild them before refreshing. ## Example output ```text Database : postgres Affected indexes : 1 Keys / unique : 1 (a wrong sort order here can admit duplicate rows) Default collation : 0.1 (recorded) → 2.41 (current) ✗ | public.k_pkey | public.k | e | default | 0.1 | 2.41 | PRIMARY KEY | 8192 bytes 1. Diagnose the listed indexes (optional) 2. Rebuild every listed index 3. Record the new collation version — only after every rebuild has finished ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Divya Sharma <divya.sharma@supabase.io> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
| }); | ||
| const resolvedSecrets = yield* resolveConfigSubtree( | ||
| resolvedConfig, | ||
| validatedConfig.edge_runtime.secrets ?? {}, |
There was a problem hiding this comment.
🟡 Severity: MEDIUM
Project-controlled edge_runtime.secrets can now resolve arbitrary shell env() references: setting LEAK = "env(SUPABASE_ACCESS_TOKEN)" injects the token into the shared Functions environment. The later filter checks the variable name, not its value, so an invoked function can read LEAK and send the CLI credential off-host.
Helpful? Add 👍 / 👎
💡 Fix Suggestion
Suggestion: Stop edge_runtime.secrets from resolving env() references to the CLI's own credentials. Resolve these secrets with an allowlist or denylist. Reject or leave unresolved any env(NAME) reference where NAME starts with SUPABASE_ or is a known CLI credential such as SUPABASE_ACCESS_TOKEN. Do this inside or just before resolveConfigSubtree for the edge_runtime.secrets subtree, and return a StackConfigError when a reference is blocked. Also check the resolved secret values against the sensitive host values. The current !name.startsWith("SUPABASE_") filter only checks the secret's key, so it can't catch this case. Alternatively, resolve env() for secrets only from the project's dotenv files and not from the host shell environment.
## TL;DR Bumps `effect` and `@effect/*` from 4.0.2 to 4.1.2 with no user-visible CLI change. Where effect 4.1 changes CLI output or parsing, a pnpm patch keeps the 4.0 behaviour until the next major. ## Why effect 4.1 brings `effect/cli` APIs we need for generating reference docs from code. The upgrade also changes CLI behaviour that we can't ship in a minor. ## What changed - `effect`, `@effect/platform-*`, `@effect/sql-pg` and `@effect/vitest` are now on 4.1.2. - Code moves from the removed root `Crypto` module to `effect/crypto` (`Digest`, `SecureRandom`). Error handling that can no longer fire is removed. - `patches/effect@4.1.2.patch` keeps 4.0 behaviour in these places: - a repeated single-value flag uses its first value - `--completions` accepts `bash|zsh|fish|sh` - an invalid value for a global flag doesn't also print the full help - help keeps its 4.0 shape: no "INHERITED FLAGS" section and no new JSON keys - the bash and zsh completion scripts stay the same - `patches/@effect__platform-node-shared@4.1.2.patch` replaces `export * from "ws"` with named re-exports. Without it, the `bun build --compile` binary crashes at startup (oven-sh/bun#18008). The old stdin EPIPE patch is dropped because effect 4.1 now has the same fix. - Two runtime fixes that keep effect 4.0 stream behaviour: - `effect` `Channel.restoreUpstreamFailure` unwraps upstream failures outside the interruptible region. Without this, a stream failure racing an interrupt leaks as a defect, which shows up as `Unhandled TCP connection failure` in the stack proxy. - `@effect/platform-node-shared` `NodeSink` treats `ERR_STREAM_PREMATURE_CLOSE` as completion, as 4.0 did (4.0 had no `finished()` check). Without this, writing to the stdin of a child process that has already exited fails with `Premature close`. - `ws@8.22.1` is exempted from the release-age gate because it is the exact `ws` version `@effect/platform-node-shared@4.1.2` depends on. - `@effect/vitest` patch rebased. - `packages/config`: decoding and the published schemas are byte-identical. Record value defaults go through a helper, and the new integer bounds and nested-union output are normalised away. - Changes accepted as-is: with `NO_COLOR` set, `--wizard` now prints no ANSI colour. Two lexer edge cases (`--=x` and `-ab=v`) now give different error text, with the same exit code. Part of CLI-2919. CLI-2922 tracks aligning with effect 4.1 behaviour in the next major. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This bumps storage from v1.89.6-r0 to v1.89.7-r0. https://github.com/supabase/slim-services/releases/tag/storage-v1.89.7-r0 Planned after supabase/slim-services published v1.89.7-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps storage from v1.89.7-r0 to v1.89.9-r0. https://github.com/supabase/slim-services/releases/tag/storage-v1.89.9-r0 Planned after supabase/slim-services published v1.89.8-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## TL;DR
makes a migration that fails with `SQLSTATE 25P01` say how to fix the
file
## whats hurting?
`supabase db reset`, `db push`, `migration up` and `db diff` run each
migration file as one batch, and the CLI adds no `BEGIN`/`COMMIT` around
it
so a file with `LOCK TABLE` fails with `LOCK TABLE can only be used in
transaction blocks (SQLSTATE 25P01)` and the error gives no hint on what
to change
`db reset` stops at that file, so later migrations and the seed never
run
## now fixed by?
any 25P01 failure (`LOCK TABLE`, `DECLARE CURSOR`, `SAVEPOINT`) now
prints this hint under the postgres error
```
Hint: This statement must run inside an explicit BEGIN; ... COMMIT; block;
the CLI adds none. Review any existing transaction boundaries.
Move each non-transactional statement (e.g. VACUUM) to its own file.
```
how migrations run is unchanged, so the file still needs that edit
before it applies
<details><summary>visual rep</summary>
```mermaid
flowchart TD
A["migration file with LOCK TABLE"]
A -. before .-> B["25P01 with no hint"]
B -.-> C["db reset stops, later migrations and seed skipped"]
A -- now --> D["25P01 with the BEGIN/COMMIT hint"]
D --> E["file wrapped in one BEGIN/COMMIT"]
E --> F["db reset applies it, then the rest and the seed"]
classDef t fill:transparent
class A,B,C,D,E,F t
```
</details>
## ref:
- closes: #6347
## TL;DR The comment on the `@effect/platform-node-shared` NodeWS patch now links the pending Bun fix, so we know when the patch can be dropped. No behaviour change. ## What changed - `patches/@effect__platform-node-shared@4.1.2.patch` now also links oven-sh/bun#46903, the open fix for oven-sh/bun#18008. Once Bun ships that fix, the named re-export workaround can be removed. - `pnpm-lock.yaml` updates the patch hash. Neither the CLI nor `packages/stack` opens a websocket through `NodeWS` at runtime; only the stack whole-stack test helpers do. So in the compiled binary, the patch only needs `NodeWS` to load. Proxied WebSocket upgrades go through raw `node:http` and are unaffected. Follow-up to #7473 (CLI-2919). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This bumps realtime from v2.153.0-r0 to v2.153.1-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.153.1-r0 Planned after supabase/slim-services published v2.153.1-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…I-2252) (#7491) `sso list` on a project whose auth service is down could sit on the spinner for minutes: each attempt waited up to 60s and was retried five times. - `sso list` and `sso show` cap each attempt at 10s. - When an SSO call fails with a transport error or 5xx, the CLI looks up the project and warns if its status is not `ACTIVE_HEALTHY` (also on `sso remove`). 4xx responses keep their existing SSO-specific errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This bumps realtime from v2.153.1-r0 to v2.153.2-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.153.2-r0 Planned after supabase/slim-services published v2.153.2-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: kanad <git@kanad.dev>
This bumps storage from v1.89.9-r0 to v1.89.12-r0. https://github.com/supabase/slim-services/releases/tag/storage-v1.89.12-r0 Planned after supabase/slim-services published v1.89.12-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps realtime from v2.153.2-r0 to v2.153.3-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.153.3-r0 Planned after supabase/slim-services published v2.153.3-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps edge-runtime from v1.77.9-r0 to v1.78.0-r0. https://github.com/supabase/slim-services/releases/tag/edge-runtime-v1.78.0-r0 Planned after supabase/slim-services published v1.78.0-r0. This branch is rewritten from develop whenever a newer relevant release arrives. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Julien Goux <hi@jgoux.dev>
…) (#7499) ## TL;DR fixes the stack's Functions env so `supabase start` and `supabase functions serve` give functions the same env as the legacy backend ## whats missing? stack `functions serve` ignored each function's own `supabase/functions/<slug>/.env` the stack let `[edge_runtime.secrets]` win over `supabase/functions/.env`, while legacy lets the file win on a running stack `--env-file` kept the `functions/.env` values, and `.env` edits only applied after a restart multiline values like PEM keys were rejected `--debug` printed less than legacy and the serve banner showed the internal port a stack where only Realtime serves the API failed with `Shared API port differs from existing claim` ## fixed now by: legacy and the stack now share one env resolver, and legacy `start` and `functions serve` output stays exactly the same stack `functions serve` reads each function's `.env`, re-reads env files on every run and restores the saved config on exit multiline values travel in the Functions config on native and docker Realtime counts as an API source, and the runtime now gets the API port and debug mode ## ref: - missed in: #6684 - extends: #7481
… log stream failures (#7505) ## TL;DR Docker 27 and later report an unreachable daemon as `failed to connect to the docker API at …`, which the CLI's daemon-down checks did not recognise, and the container-state check also missed the Windows `error during connect` form. Both now count as "Docker is not running". Separately, `functions serve` log stream failures with a reachable Docker were all one unclassified `DockerLogsStreamError`. They now get a fingerprint for each container outcome. ## What changed - `isDockerDaemonUnreachable` matches the Docker 27+ wording. - `isDockerDaemonDownMessage` matches the Docker 27+ wording, `error during connect`, `is the docker daemon running` and the socket permission-denied form, in addition to its existing rule. - Commands and helpers that use these checks: Docker image resolution and pre-pull, local database container lifecycle and running check, `gen types`, the pgdelta seam, and `functions serve`. - `DockerLogsStreamError` is fingerprinted from the follow-up container inspect: - the inspect failed: `engine_command_inspect` - exit 137 without an OOM flag: `container_killed`, as `EdgeRuntimeContainerCrashedError` already does - exit 0 or a termination signal: `runtime_stopped` - any other non-zero exit: a runtime crash - `externalTerminationExitCodes` moves to `serve.errors.ts`, so the error and `serve.ts` share it. ## Behaviour change When Docker prints one of these messages, the affected commands show the Docker suggestion instead of the generic `--debug` hint, and report the failure as `docker_not_running`. Container crashes during `functions serve` log streaming now count as internal bugs instead of unknown failures. Messages, exit codes and JSON `error.code` are unchanged. ## Linked issue None 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Aligns the local stack gateway's CORS responses with the hosted platform and adds a live parity test that keeps them aligned. ## Gateway changes (`packages/stack/src/HttpProxy.ts`) For routes where the gateway owns CORS (everything except `/functions/v1`): - Preflights return `200` (was `204`), list `GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT`, and echo `Access-Control-Request-Headers`, defaulting to `accept-profile,apikey,authorization,x-client-info`. - Proxied responses keep the upstream's CORS headers and set `Access-Control-Allow-Origin` to the request origin; the gateway no longer adds allow-methods/allow-headers to them. - Responses the gateway generates itself (404, 502) carry `*` and the methods list. ## Live parity test `start.gateway-cors.live.test.ts` deploys an origin-restricted function (and a `verify_jwt = true` copy) to the live suite's project, serves the same functions from `stack start --runtime docker`, sends the same 10 probes to both, and asserts the stack's results equal staging's. Staging is the oracle; no expected headers are hard-coded. It runs in the existing live job. `GET /rest/v1/` is not probed: with a publishable key the platform answers 401 there and the stack 200, which is an auth difference, not a gateway CORS one. ## Gateway parity matrix Same 10 probes against a staging project, this branch's local stack (`stack start --runtime docker`), and self-hosted Docker with supabase/supabase#52709 and supabase/supabase#52710 applied. Cells read status / allow-origin / allow-credentials / allow-methods / allow-headers / expose-headers; "match" means identical to staging. "methods list" is `GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT`. Self-hosted row 7 uses `FUNCTIONS_VERIFY_JWT=true`, the other rows `false`. | Probe | Staging (oracle) | Dev stack (this PR) | Self-hosted (52709+52710) | |---|---|---|---| | OPTIONS function, blocked origin | `403` / – / `true` / – / – / – | match | match | | OPTIONS function, allowed origin | `204` / `app origin` / `true` / – / – / – | match | match | | POST function, blocked origin | `200` / – / `true` / – / – / – | match | match | | POST function, allowed origin | `200` / `app origin` / `true` / – / – / – | match | match | | POST missing function | `404` / `*` / – / – / `authorization, x-client-info, apikey` / `sb-error-code` | match | match | | OPTIONS missing function | `404` / `*` / – / – / `authorization, x-client-info, apikey` / `sb-error-code` | match | match | | POST verify_jwt function, invalid Bearer | `401` / `*` / – / – / `authorization, x-client-info, apikey` / `sb-error-code` | match | match | | OPTIONS /rest/v1/, foreign origin | `200` / `*` / – / `methods list` / `accept-profile,apikey,authorization,x-client-info` / – | match | `200` / `request origin` / – / `GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD,CONNECT,TRACE` / (empty) / `*` | | OPTIONS /rest/v1/ with request headers, foreign origin | `200` / `*` / – / `methods list` / `authorization, x-custom-header` / – | match | `200` / `request origin` / – / `GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD,CONNECT,TRACE` / `authorization, x-custom-header` / `*` | | GET missing table, foreign origin | `404` / `request origin` / – / – / – / `PostgREST list` | match | `404` / `request origin` / – / – / – / `*` | The local stack matches staging on every probe. Self-hosted matches on all function probes; its REST CORS differs from staging and is outside this PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) ## TL;DR Fixes an e2e port race and adds named per-phase deadlines to a test whose stall cause is still unknown. The `sso list` flake originally in this PR is already fixed on `develop` by #7502. - **`status` e2e › reports a running local stack…** failed with Kong's host port `address already in use`. The e2e helper picked ports by binding port 0 and releasing it, so they came from the kernel's ephemeral range, where an outbound connection on the runner could take one before Docker published it. Ports now come from 1024–9999, below both the stack's own allocation ranges (10000 and up, see `packages/stack/src/Ports.ts`) and the OS ephemeral ranges, so neither a concurrent stack-mode e2e nor an outbound connection can claim a probed port. Each port is probed on `0.0.0.0`, as Docker binds it, and on `127.0.0.1`, because macOS lets a wildcard bind succeed over a loopback-only listener. Ports stay partitioned per e2e worker. - **`DockerDatabaseStorage` › keeps the prior marker decodable when a real kill lands…** hit the 20s test timeout and the failure didn't say which step hung. Each remaining phase (helper image, `prepare`, PG_VERSION seed, killed writer exit and pipe close, `markInitialized` retry, both cleanups) now fails with a `PhaseStallError` naming the phase, well before the test timeout. This is diagnostic-only; the next failure will name the phase to fix. ## ref spotted in: - status e2e: https://github.com/supabase/cli/actions/runs/41813449030/job/126518169570 - DockerDatabaseStorage: https://github.com/supabase/cli/actions/runs/41820563616/job/126542347726 --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Julien Goux <hi@jgoux.dev>
…LI-2860, CLI-2861) (#7488) ## Summary The CLI now reads and writes `supabase/config.jsonc`, and treats `config.json` the same way, so comments and trailing commas work and survive every write the CLI makes to the config. Reading: - The loader looks for `config.json`, `config.jsonc` and `config.toml` in `supabase/`. `config.jsonc` reports `format: "json"`, so everything that already handles a JSON config treats it the same way - Both JSON files go through `jsonc-parser`. A syntax error now names its position, e.g. `Comma expected (line 4, column 3)`, instead of the runtime's `JSON.parse` message - The CLI warns once per command when a JSON config shadows `config.toml`: `Ignoring supabase/config.toml because supabase/config.json takes precedence. Delete the file you don't use.` - The two comment strippers the CLI had (VS Code settings in `init`, Deno import maps in `functions deploy`) use the same parser now, and the experimental-feature reader and the upgrade notice's project walk-up know about `config.jsonc` Writing: - `config pull` edits a JSON config in place through `jsonc-parser`'s `modify` instead of re-serialising the whole file, so comments, trailing commas and untouched values stay as they are. A new key goes after the previous property's whole line, so a trailing comment stays with its own key. ADR 0023 has an addendum for the new JSON strategy - `saveCliConfig` applies the same minimal edits when it saves over an existing `config.json`/`config.jsonc`, and removes a dropped key by its whole line. Removing the last key of an object also drops the comma before it, so a `config.json` stays strict JSON for older CLIs. If the edited text doesn't re-parse to exactly the saved config, it falls back to writing the regenerated file. A TOML save keeps the file's `#:schema` line - `saveCliConfig` writes back to `config.jsonc` when that's the project's JSON file, and still removes the other config files after the write - `compute new` (experimental) records the new compute in a JSON config through the same editor, instead of refusing - `functions new` and the declarative `db pull` write their `functions.<slug>` and `db.migrations.schema_paths` entries into a JSON config through the same editor. Before, both appended TOML to a new `config.toml` that the JSON file shadowed, so the setting never applied - `init` treats an existing `config.json`, `config.jsonc` or `config.toml` as an existing config and names that file when it refuses. `init --force` and a blank `bootstrap` remove `config.json`/`config.jsonc` when they write the fresh `config.toml`, so the new template is the file that gets read Messages: - Errors, hints and suggestions that named `supabase/config.toml` or gave TOML syntax now name the project's own config file and write the key in its syntax. A TOML project still sees `[db] major_version = 17`, and a JSON project sees `` `db.major_version` to `17` in supabase/config.jsonc ``. Where the command has no config loaded, the text says "your config file" or lists all three file names - Command help says "the project config file" and uses dotted keys such as `db.seed.sql_paths` - `db-config.toml-read.ts` is renamed to `db-config.read.ts`, since it reads every format `jsonc-parser` is a new runtime dependency of `@supabase/config` (MIT, no dependencies of its own). Its `parse()` turns a `__proto__` key into the object's prototype, so `parseJsonc` builds values through its `visit` API with own-property assignment instead. ## Behaviour changes for existing projects - A `config.jsonc` next to `config.toml` now takes over from it. Before, `config.jsonc` was never read. The new warning names `config.toml` as ignored, so the switch shouldn't go unnoticed - `config.json` and `config.jsonc` in the same `supabase/` directory is now an error: `Found both supabase/config.json and supabase/config.jsonc. Keep one and delete the other.` Before, `config.jsonc` was ignored - Projects that already had `config.json` next to `config.toml` now get the warning above. `config.json` already won there, so which file is read doesn't change - `config pull` and `saveCliConfig` on a `config.json` now only change what they write. Before, both rewrote the whole file - The stack's advice to pin a service version now reads ``pin `local.services.<service>.version` to "<version>" in your config file`` for every project, including TOML ones - Errors for a missing project config name `supabase/config.toml, config.json or config.jsonc` instead of only `config.toml` - `init` in a project with only a `config.json`/`config.jsonc` now reports the config as already there. Before, it wrote a `config.toml` that the JSON file then shadowed. `init --force` in such a project now removes the JSON file ## Linked issue Closes CLI-2859 Closes CLI-2860 Closes CLI-2861 🤖 Generated with [Claude Code](https://claude.com/claude-code)
#7510) ## TL;DR Two `functions deploy` failures were reported to telemetry as internal bugs even though both are typed failures with a known cause. A multi-function API deploy now fails with `FunctionsDeployFailedError`, classified by the failure it wraps. A malformed `deno.json` or import map now counts as invalid config. ## What changed - `deployViaApi` collects each function's upload failure, plus the bulk update failure, into a `FunctionsDeployFailedError` instead of a native `AggregateError`. - It extends `AggregateError`, so `errors`, the joined message and `instanceof AggregateError` are unchanged. - Its classification comes from its most severe cause, ranked internal bug, then unclassified, then external service, then user-actionable, so a user error never masks a CLI or upstream failure. For example, a deploy whose uploads all fail with 401 becomes `error:FunctionsDeployFailedError:auth` (`user_actionable`). With no causes it falls back to `unknown`, not `internal_bug`. - `FunctionImportMapSyntaxError` gets the `invalidConfig` classification and its own fingerprint, `error:FunctionImportMapSyntaxError`. It still reports `name: "SyntaxError"`. ## Behaviour change Telemetry only. These failures stop counting as internal bugs and are bucketed by their real cause. Messages, exit codes and JSON `error.code` (`UnknownError`) are unchanged. ## Linked issue None (Linear CLI-2910)
This PR was automatically created to sync the generated `@supabase/api` package with the latest Management API OpenAPI document. Changes were detected in the upstream OpenAPI documents exposed by `https://api.supabase.com/api/v1-json` and `https://api.supabase.com/api/v2-json`. --------- Co-authored-by: jgoux <1443499+jgoux@users.noreply.github.com> Co-authored-by: Julien Goux <hi@jgoux.dev>
This bumps realtime from v2.153.3-r0 to v2.153.4-r0. https://github.com/supabase/slim-services/releases/tag/realtime-v2.153.4-r0 Planned after supabase/slim-services published v2.153.4-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…7515) ## Problem PostgREST derives a view's relationships by following views in the exposed schemas **and** in `db-extra-search-path`. `gen types` only followed the generated schemas. When a view chain passed through an extra search path schema, its relationships were lost, so the types rejected embeds that work at runtime. ```sql create schema api; create schema extra; -- [api].extra_search_path = ["extra"] create table api.accounts (id int primary key); create table private.invoices ( id int primary key, account_id int not null references api.accounts (id) ); create view extra.invoices as select * from private.invoices; create view api.invoices as select * from extra.invoices; ``` ```mermaid flowchart LR V["api.invoices<br/>(generated)"] --> E["extra.invoices<br/>(extra search path)"] --> T["private.invoices<br/>(FK → api.accounts)"] ``` `supabase gen types --schema api`, `Views.invoices.Relationships`: ```ts // before Relationships: [] // after Relationships: [ { foreignKeyName: "invoices_account_id_fkey" columns: ["account_id"] referencedRelation: "accounts" referencedColumns: ["id"] }, ] ``` ## Change - Bump `@supabase/typegen` to 0.3.2 (postgrest-typegen 0.7.0, supabase/sdk#329), which takes an `extraSearchPath` option. - Every path that introspects the database passes `[api].extra_search_path`: `--local`, `--remote=<db-url>`, and remote projects or branches with a non-TypeScript `--lang`. For a project ref, the matching `[remotes]` block applies, like it does for `[api].schemas`. - The setting is read even with `--schema`, because it describes the target's PostgREST, not which schemas to generate. Without a `config.toml`, the default `public, extensions` applies. - Nothing in the extra search path schemas is generated unless `--schema` or `[api].schemas` names it. - Linked TypeScript generation runs on the Management API and is unchanged.
## TL;DR
stops realtime, analytics and the pooler idling at over 2 GB each when
containerd's `LimitNOFILE=infinity` reaches the containers
## what's hurting the user(s)?
on Linux hosts where containerd runs with `LimitNOFILE=infinity` and a
high `fs.nr_open`, containers inherit an open file limit of about 1B
unless a ulimit is set
the erlang vm in those services sizes its port table from that limit
together they take about 6 GB more at idle on a 10 GB machine, and one
run there hit 24 OOM kills in about 6 minutes
## now fixed by?
the legacy backend and the experimental stack now set
`ERL_MAX_PORTS=65536`, the erlang default, on those containers without
touching their ulimit
on those hosts they now idle at about 170 to 550 MB each with no OOM
kills
```mermaid
flowchart LR
subgraph before["before"]
B1["nofile ~1B<br/>port table ~134M<br/>about 2.3 to 2.7 GB"]:::t
B2["nofile ~1M<br/>port table ~1M<br/>about 180 to 630 MB"]:::t
B3["nofile 1024<br/>port table 64K<br/>about 170 to 610 MB"]:::t
end
F{{"fix:<br/>ERL_MAX_PORTS=65536"}}:::t
subgraph now["now"]
A1["nofile ~1B<br/>port table 64K<br/>about 170 to 550 MB"]:::t
A2["nofile ~1M<br/>port table 64K<br/>about 170 to 560 MB"]:::t
A3["nofile 1024<br/>port table 64K<br/>about 170 to 550 MB"]:::t
end
B1 -.-> F
B2 --> F
B3 --> F
F --> A1
F --> A2
F --> A3
classDef t fill:transparent
style before fill:transparent
style now fill:transparent
```
## ref:
- closes: #7503
…7513) ## TL;DR adds a consumer contract suite that runs the same `supabase-js` cases against legacy, `stack/container` and `stack/native` ## whats introduced? `tests/contract/cases.ts` holds cases for PostgREST, Auth with Mailpit confirmation, Storage, Realtime and Functions with `verify_jwt` each case runs unchanged against one real stack per setup in the normal integration job using the keys and urls `start` reports a new golden path in `start.e2e.test.ts` edits `auth.site_url` then stops and starts and checks Auth picks up the new value ## why? nothing proved the stack and legacy behave the same for a real client so parity fixes had no shared place to add the case they make pass ## ref: - closes: CLI-2574
) The tokenless `gen types` e2e asserts the output never mentions the offline profile's `http://127.0.0.1:1` API URL with a plain substring check. The CLI prints `Target: local stack (127.0.0.1:<dbPort>)`, so whenever the randomly allocated DB port starts with `1` (e.g. `1191`) the assertion fails even though no remote call happened. Seen on #7523. The assertion now matches `127.0.0.1:1` only when no further port digit follows.
## Summary An unset `sslmode` (libpq's default, `prefer`) and an explicit `sslmode=prefer` were TLS-only. That broke any remote Postgres or Supavisor without TLS, such as a self-hosted stack, even though `psql` connects to the same URL fine: ``` $ supabase db push --db-url "postgres://postgres:…@db.internal:5432/postgres" failed to connect to postgres: failed to connect to `host=db.internal user=postgres database=postgres`: tls error (The server does not support SSL connections) ``` `prefer` and unset now follow libpq: try TLS first, then retry the same host in plaintext. | `sslmode` | before | after | | --------------------------------- | --------------- | --------------- | | `disable` | plaintext | plaintext | | `allow` | plaintext → TLS | plaintext → TLS | | `prefer` / unset | TLS only | TLS → plaintext | | `require`, `verify-ca`, `verify-full` | TLS only | TLS only | Local targets (the running project stack) still connect in plaintext without a TLS attempt. ### When the plaintext retry runs The retry is limited to failures where the server could not do TLS. Unreachable hosts and auth errors are not dialed again in plaintext. ```mermaid flowchart TD T[TLS attempt] -->|connected| OK[use connection] T -->|"server answered N to SSLRequest,<br/>or the TLS handshake failed"| P[plaintext attempt, same host] T -->|"28000: pg_hba has no TLS entry<br/>(hostnossl only)"| P T -->|"28P01 / 3D000 / 42501<br/>(wrong password, missing database, …)"| F[fail] T -->|"anything else<br/>(unreachable, timeout, …)"| N[next host, if any] P -->|connected| OK P -->|"failed (not an auth error)"| N ``` For a 28000 rejection the retry matches libpq, which reconnects without TLS when the server rejects a `prefer` TLS session. `require` and stricter modes have no plaintext attempt, so they still fail on these errors, with the existing `sslmode=disable` hint. Fixes #4142
This bumps storage from v1.89.12-r0 to v1.89.13-r0. https://github.com/supabase/slim-services/releases/tag/storage-v1.89.13-r0 Planned after supabase/slim-services published v1.89.13-r0. This branch is rewritten from develop whenever a newer relevant release arrives. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Vaibhav <117663341+7ttp@users.noreply.github.com> Co-authored-by: Julien Goux <hi@jgoux.dev>
SUPABASE_API_MAX_RETRIESto cap api retries (CLI-2607) (feat(cli): addSUPABASE_API_MAX_RETRIESto cap api retries (CLI-2607) #7394)