Repository navigation
Conversation
Add the registry, pure picker, flag bindings, project env loader and CliConfigValues service that later changes migrate the readers onto. No command reads through them yet. @supabase/config/internal gains the parse + merge and decode + validate stages loadCliConfig is built from.
Decode config once per load and read values from that result, keep package errors visible by tag, fail on secret decrypt errors, scope linked-project credentials by link file, and close the precedence bypasses (rawDocument, registry-name lookups, duplicate flag assignments). The env loader moves to shared/config and the config package gains an explicit validateRemotes option plus a parse/merge split for document-derived env discovery.
Replaces resolveDbPassword and the explicit-ref env rule with the loader's linked-target credential scoping. Adds a shared DbPasswordFlagsError rejecting --password with --db-url or --local, makes gen types --local read [db].password, and routes bootstrap config writes through writeThrough.
Seed flags (--include-seed, --no-seed, --sql-paths), --use-pg-delta and --password on db push/reset/diff/pull are built from config keys and the effective values come from the config snapshot. Seeding into a target that matched a [remotes.*] block now asks first (--yes confirms; non-interactive runs fail before any write). The local Docker project id for pg-delta and the local-db probe comes from the snapshot.
readDbToml is now a projection of a CliConfigValues snapshot: flag, shell, project .env, config (matched remote over base), then default. The per-key remote overlay is retired and remoteOverrideKeys is always empty.
…Values start, stack-config, status gates, storage credentials and the services version lookup now take their effective values from the CliConfigValues snapshot instead of re-deriving shell/dotenv/remote precedence by hand. Commands that reach these paths provide the snapshot layer.
Local Docker readers (local-config-values, bootstrap, container inputs, project context, functions config) take their effective values from the CliConfigValues snapshot instead of hand-written env/remote precedence. The Invalid*EnvOverrideError classes collapse into CliConfigValueError, projectEnvValues holds only supabase/.env* file values, and the Docker project id is the sanitized workdir name unless project_id or SUPABASE_PROJECT_ID is set.
Build the local project context on the shared snapshot helpers and read process.env behind the pinned db test layer. Update tests that asserted the previous remote-over-env order.
Drop the reset-only seed flag overlay; the snapshot already applies SUPABASE_DB_SEED_ENABLED and the bound seed flags. Add reset tests for env enable/disable and --sql-paths over env.
…the snapshot Resolve experimental feature opt-ins through the shared key precedence with their strict 0/1 codec, and load storage, seed buckets and gen signing-key config through CliConfigValues so remote selection by env and flag/env overrides apply uniformly.
- Coerce config-tier values through the key codec into the draft before decode, so env() references, case-variant bool tokens and single-string glob lists decode as before; add a weak glob codec for db.seed.sql_paths and db.migrations.schema_paths. - Gate db.ssl_enforcement env overrides on the section, and assert every optional schema section is gated or explicitly exempt. - Add a hidden option to key.flag that keeps the config binding, and re-hide db pull --use-pg-delta. - Type context-default keys such as projectId as plain values, sanitize project_id once, and drop the project-id shims. - Require CliConfigValues in readDbToml and the db config resolver instead of building a flagless fallback; wire cliConfigValuesLayer into every command that reaches them.
…ackage dotenv loader
…ts --password flag
…s snapshot Exposes the loaded document on the snapshot, lets a load tolerate an unreadable .temp/project-ref, and carries the merged document on value failures so secrets set can salvage edge_runtime.secrets without a second loader.
Deletes the env-override and remote-wins plumbing, the project-environment loader, the deprecated CommandSettings.dbPassword and the inert resolver params. project_id now comes from the config snapshot, start reads dotenv private keys from the snapshot sources, and the modules the config foundation depends on move out of command-internal into shared/config.
Restricts process.env and Bun.env across apps/cli/src, except the provider layer, the env loader, the node shim and compute stack templates.
…napshot functions serve, functions new, gen types, inspect report, compute and the db toml reader resolve flag > shell > project .env > config > default through CliConfigValues. Removes the private serve .env loader, resolveLocalProjectId, valueErrorMessage and snapshot declaredAt; folds the sanitizeProjectId copies into shared/config/project-id.
…cedence-to-flags-env-configtoml-defaults
…cedence-to-flags-env-configtoml-defaults
…cedence-to-flags-env-configtoml-defaults
…snapshot Partial [auth.email.smtp] tables load again, a config-tier env() reference keeps its origin on numeric and boolean keys, load-time warnings print once per runtime, config push counts only values it will send, and config pull writes go through writeThrough. The remaining package loaders move behind the CliConfigValues snapshot.
Extend the oxlint restrictions to env imports, namespace imports and globalThis.process, list the audited ambientEnvironment callers, and make the code-structure guard reject registry env names as literals and package loader imports outside the foundation.
…hange-config-precedence-to-flags-env-configtoml-defaults # Conflicts: # apps/cli/src/command-internal/argv-flag-reconcile.ts # apps/cli/src/command-internal/config-validate.ts # apps/cli/src/command-internal/config-validate.unit.test.ts # apps/cli/src/command-internal/db-bootstrap/bootstrap-config.ts # apps/cli/src/command-internal/db-bootstrap/local-container-inputs.ts # apps/cli/src/command-internal/db-bootstrap/shadow-cache.ts # apps/cli/src/command-internal/db-bootstrap/start-local-database.ts # apps/cli/src/command-internal/db-config.toml-read.ts # apps/cli/src/command-internal/db-config.toml-read.unit.test.ts # apps/cli/src/command-internal/docker-ids.unit.test.ts # apps/cli/src/command-internal/experimental-gate.unit.test.ts # apps/cli/src/command-internal/global-flags.ts # apps/cli/src/command-internal/local-config-values.ts # apps/cli/src/command-internal/local-config-values.unit.test.ts # apps/cli/src/command-internal/local-project-context.ts # apps/cli/src/command-internal/local-project-context.unit.test.ts # apps/cli/src/command-internal/migration-apply.ts # apps/cli/src/command-internal/migration-apply.unit.test.ts # apps/cli/src/command-internal/pg-dump.run.ts # apps/cli/src/command-internal/project-environment.unit.test.ts # apps/cli/src/command-internal/seed-buckets.ts # apps/cli/src/command-internal/stack-config.ts # apps/cli/src/command-internal/stack-shadow-cache.ts # apps/cli/src/command-internal/supabase-env.ts # apps/cli/src/command-internal/viper-env.unit.test.ts # apps/cli/src/commands/config/config.load.ts # apps/cli/src/commands/db/diff/SIDE_EFFECTS.md # apps/cli/src/commands/db/dump/SIDE_EFFECTS.md # apps/cli/src/commands/db/dump/dump.handler.ts # apps/cli/src/commands/db/dump/dump.integration.test.ts # apps/cli/src/commands/db/pull/SIDE_EFFECTS.md # apps/cli/src/commands/db/pull/pull.command.ts # apps/cli/src/commands/db/pull/pull.integration.test.ts # apps/cli/src/commands/db/reset/SIDE_EFFECTS.md # apps/cli/src/commands/functions/deploy/SIDE_EFFECTS.md # apps/cli/src/commands/functions/deploy/deploy.integration.test.ts # apps/cli/src/commands/functions/download/SIDE_EFFECTS.md # apps/cli/src/commands/functions/download/download.integration.test.ts # apps/cli/src/commands/functions/new/new.handler.ts # apps/cli/src/commands/functions/serve/SIDE_EFFECTS.md # apps/cli/src/commands/functions/serve/serve.handler.ts # apps/cli/src/commands/functions/serve/serve.integration.test.ts # apps/cli/src/commands/gen/bearer-jwt/bearer-jwt.handler.ts # apps/cli/src/commands/gen/gen.signing-keys-config.ts # apps/cli/src/commands/gen/signing-key/signing-key.handler.ts # apps/cli/src/commands/gen/types/SIDE_EFFECTS.md # apps/cli/src/commands/gen/types/types.handler.ts # apps/cli/src/commands/inspect/report/report.config.ts # apps/cli/src/commands/inspect/report/report.config.unit.test.ts # apps/cli/src/commands/link/SIDE_EFFECTS.md # apps/cli/src/commands/link/link.integration.test.ts # apps/cli/src/commands/migration/list/SIDE_EFFECTS.md # apps/cli/src/commands/migration/repair/SIDE_EFFECTS.md # apps/cli/src/commands/migration/squash/SIDE_EFFECTS.md # apps/cli/src/commands/migration/squash/squash.handler.ts # apps/cli/src/commands/secrets/set/set.handler.ts # apps/cli/src/commands/seed/buckets/buckets.integration.test.ts # apps/cli/src/commands/services/SIDE_EFFECTS.md # apps/cli/src/commands/start/SIDE_EFFECTS.md # apps/cli/src/commands/start/start.handler.ts # apps/cli/src/commands/storage/storage.frame.ts # apps/cli/src/shared/cli/code-structure.unit.test.ts # apps/cli/src/shared/functions/deploy.ts # apps/cli/src/shared/functions/download.ts # apps/cli/src/shared/functions/functions-config.ts # apps/cli/src/shared/functions/serve.ts # apps/cli/src/telemetry/telemetry-state.layer.unit.test.ts # packages/config/docs/cli-config-loading.md # packages/config/src/io.ts
There was a problem hiding this comment.
Superseded by a newer AI review
🤖 AI Review
Verified all seven findings from both independent reviews. Confirmed six, including two major regressions: stale config snapshots across functions serve restarts and missing decryption of stack Edge Runtime secrets. Refuted the numeric-boolean complaint using pre-existing coercion code and tests. Verification used code inspection and isolated codec execution; full runtime tests were not run.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | apps/cli/src/command-internal/stack-config.ts:411 |
correctness |
codex | Stack startup forwards encrypted Edge Runtime secrets as ciphertext, breaking functions that require their decrypted values. |
| 🟠 MAJOR | apps/cli/src/config/cli-config-values.layer.ts:473 |
caching |
codex | functions serve reuses its initial config and project dotenv values across watched restarts, so external edits no longer take effect. |
| 🟡 MINOR | apps/cli/src/config/cli-config-values.layer.ts:331 |
validation |
codex | The snapshot accepts non-object JSON config roots as an empty/default config instead of rejecting them. |
| 🟡 MINOR | apps/cli/src/config/cli-config-key.ts:121 |
correctness |
claude | uintCodec accepts string integers above Number.MAX_SAFE_INTEGER and silently rounds some of them, while rejecting the corresponding typed numeric config values. |
| 🟡 MINOR | apps/cli/src/commands/gen/gen.signing-keys-config.ts:345 |
diagnostics |
codex | Signing-key guidance identifies config.toml even when the command loaded config.json. |
| ⚪ NIT | apps/cli/src/command-internal/experimental-feature.ts:87 |
documentation |
codex | The experimental-feature resolver documentation incorrectly describes its shell override as accepting strictly 0 and 1. |
Refuted findings (kept for transparency, not posted as review comments)
apps/cli/src/config/cli-config-key.ts:138(correctness): boolCodec.fromConfig treats non-zero numbers, including fractions and NaN, as true instead of rejecting them, unlike the stricter environment-string grammar.
Refuted: The coercion occurs, but treating it as invalid behavior conflicts with the established weak decoding contract. The default-branch resolveBool explicitly accepts numeric truthiness, and local-config-values.unit.test.ts:1776–1779 explicitly expects both 123 and 1.5 to become true. The PR retains the same rule in local-config-values.ts:678–681; typed numeric values and environment strings intentionally use different grammars.
Stats
Claude findings: 2 · Codex findings: 5 · Confirmed: 6 · Refuted: 1 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: auto · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
|
/ai-review |
There was a problem hiding this comment.
🤖 AI Review
All five supplied findings are confirmed, with corrections to the reset load-order detail and duplicate-prompt scope. No findings overlap. Verification covered the reported issues and related code paths, not the entire 470-file PR.
Findings
| Severity | Location | Category | Sources | Claim |
|---|---|---|---|---|
| 🟠 MAJOR | apps/cli/src/config/cli-config-values.layer.ts:191 |
configuration |
codex | A shell-only dotenvx private key with a high numeric suffix, such as DOTENV_PRIVATE_KEY_2026, can be omitted from the environment snapshot, causing otherwise valid encrypted configuration to fail decryption. |
| 🟡 MINOR | apps/cli/src/command-internal/db-config.toml-read.ts:334 |
error-handling |
claude | The database TOML reader wraps CliConfigValueError and CliConfigFlagConflictError as DbConfigLoadError, losing their error identity. This affects db push and the linked database resolver used by db reset, despite the separate password-resolution path preserving those tags. |
| 🟡 MINOR | apps/cli/src/command-internal/db-target-flags.ts:263 |
correctness |
claude | An empty password flag is excluded from configuration assignments but remains Some("") in parsed handler flags, so the direct-target guard incorrectly rejects it with --local, --db-url, or a default-local target. |
| 🟡 MINOR | apps/cli/src/command-internal/seed-remote-consent.ts:42 |
correctness |
codex | A matched remote declaring db.seed.enabled = 1 enables seeding through the configuration codec but is incorrectly treated as lacking explicit seed authorization, potentially rejecting a run that cannot prompt. |
| ⚪ NIT | apps/cli/src/command-internal/db-push-core.ts:233 |
ux |
claude | Interactive db push --include-seed asks about seeding twice when pending seeds target a matched remote requiring consent: once before writes and again after migrations. |
Stats
Claude findings: 3 · Codex findings: 2 · Confirmed: 5 · Refuted: 0 · Uncertain: 0
Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run
This review runs once per PR. A maintainer can request another with a /ai-review comment.
…hange-config-precedence-to-flags-env-configtoml-defaults # Conflicts: # apps/cli/src/command-internal/db-config.toml-read.ts # apps/cli/src/command-internal/db-pull-run.ts # apps/cli/src/command-internal/diff-engine.ts # apps/cli/src/command-internal/diff-engine.unit.test.ts # apps/cli/src/commands/db/diff/SIDE_EFFECTS.md # apps/cli/src/commands/db/diff/diff.handler.ts # apps/cli/src/commands/db/pull/SIDE_EFFECTS.md # apps/cli/src/commands/db/pull/pull.integration.test.ts # apps/cli/src/commands/db/reset/reset.handler.ts # apps/cli/src/commands/db/reset/reset.integration.test.ts
Drop the SUPABASE_EXPERIMENTAL_PG_DELTA alias and the env-alias machinery only it used. Read experimental.pgdelta.enabled through the resolved config in the db config reader and the diff handler. Keep the pgdelta section exempt from env section gating so the env rollback works without the section. Update goldens, tests and docs for the pg-delta default.
Summary
Every config value now resolves in one order, in every command:
explicit flag > shell env > project env files > config (config.json over config.toml, a matched [remotes.*] block over the base) > defaultProject env files are
.env.<SUPABASE_ENV>.local,.env.local,.env.<SUPABASE_ENV>and.env. They are read fromsupabase/and then the project root, andSUPABASE_ENVdefaults todevelopment.Before this change, each command family overlaid flags, env and remotes by hand, and the families disagreed:
[remotes.*]block beat an explicitSUPABASE_*variable.config diffandconfig pushcould see different values.--passwordwas silently dropped when combined with--db-url.ADR 0001 already defined this order, so this is mostly making the code actually follow it.
Closes CLI-1885, closes CLI-2214. The decisions are recorded in ADR 0031.
How it works
Before, every command decided for itself where a setting came from, and they didn't agree. Now one service answers "what's the value of X?" for every command, and it always asks the same sources in the same order.
The problem
A setting like "should
db pushseed?" can come from five places:--include-seed)export SUPABASE_DB_SEED_ENABLED=true)supabase/.env,.env.local, ...)config.toml, where a matching[remotes.staging]block beats the base[db.seed]Each command family used to walk that list by hand, in its own order, with its own parser. So
db pushandstartcould look at the same setting and get different answers, a remote block could beat your shell env in one command but not another, andconfig diffcould show something different from whatconfig pushwould send.The service:
CliConfigValuesThink of it as a librarian. You don't go into the stacks yourself; you ask the librarian. It checks the five shelves in one fixed order and hands you the first answer it finds, with a note saying which shelf it came from.
A command uses it in three steps.
1. Load the resolved config once per run.
This reads the flags, the env and the env files, parses
config.toml, picks the matching[remotes.*]block, applies the order above and validates the whole config. If anything is invalid (for exampleSUPABASE_STUDIO_PORT=abc), the command stops here, and the error names where the bad value came from.2. Ask for a value by key.
You get the value plus its origin. That origin is what lets the CLI say things like
SUPABASE_AUTH_SITE_URL (shell) overrides auth.site_url in [remotes.staging]or(from SUPABASE_API_MAX_ROWS in supabase/.env).3. Bind flags to keys instead of reading them by hand.
The flag isn't a separate boolean the handler has to remember to merge in. It is declared as the flag tier of
db.seed.enabled, so the resolved config already knows about it.Where the keys come from
CliConfigKeysis generated from the config schema (CliConfigSchema). Every leaf inconfig.tomlbecomes a key with:db.seed.enabledSUPABASE_plus the path in upper snake case, soSUPABASE_DB_SEED_ENABLEDNobody writes the 360 or so keys by hand. Add a field to the schema and it gets an env override and a parser for free. The only hand-written parts are exceptions, such as codec overrides, exclusions and section gates like "SMTP env vars only apply if
[auth.email.smtp]exists".A worked example
--include-seedSUPABASE_DB_SEED_ENABLED.env*[remotes.staging.db.seed][db.seed](base)Seeding is on, from the flag. Without the flag, the shell value wins (still on, origin shell). Before this PR, the remote block's
falsewould have beaten the shell variable, which is the headline breaking change. And because seeding is on for a project that matched a remote block that doesn't itself turn seeding on, the CLI asks for confirmation before seeding.How it relates to
config.tomlconfig.tomlisn't replaced. It's shelf 4. The@supabase/configpackage still parses it, merges the matching remote and decodes it. The service calls those package stages and layers flags and env on top, and commands can no longer call the package loaders directly.The resolved config gives two views of the whole config:
resolvedConfig.loaded: what you declared (file plus flags and env), with no defaults.config pushandconfig diffuse this, so push never sends a default you didn't write.resolvedConfig.materialized: the same with defaults applied. Used by things that need a complete config to run, likestart, local Docker and stack.What stops this drifting back
SUPABASE_*config env name or imports the package config loaders.oxlintbansprocess.envandBun.envacross the CLI.tsc.Design
It's a big diff, sorry - but most of it is commands moving onto the new service. The interesting parts are
apps/cli/src/config/cli-config-*.ts, the guard tests incode-structure.unit.test.tsand ADR 0031. If you disagree with any of the behaviour calls in the table below, that's totally fine, I'd rather we settle them here than afternextships.CliConfigValuesis the only service that resolves values.load({ workdir, projectRef })returns a memoisedResolvedCliConfig.resolvedConfig.get(key)returns the value and the tier it came from.resolvedConfig.loadedis the declared config: file, flags and env, with no defaults.config pushandconfig diffuse it.resolvedConfig.materializedis the declared config with defaults applied.CliConfigSchema. Each leaf gets the env nameSUPABASE_+ its upper-snake path, and a codec derived from its type. Section gates, codec overrides and exclusions are hand-written annotations.key.flag(...), so "explicitly passed" is part of the type rather than a convention. If two flags set the same key to different values, the first load fails withCliConfigFlagConflictError.@supabase/config/internalexposes the pipeline stages: parse, merge a selected remote, decode. Only the foundation calls them.loadCliConfig,resolveCliConfigSubtree,loadCliProjectEnvironment) outside the foundationkey.flagoxlintbansprocess.env,Bun.env,globalThis.processandenvimported fromnode:processacrossapps/cli/src.withCliConfigFlagsfailstsc.[remotes.*]block sets, the CLI prints one WARN per key.--debuglists the origin of every non-default value.config pushlabels env-sourced rows and prints a one-line summary of them, even with--yes.CommandSettingsreadsSUPABASE_PROJECT_IDfrom the shell only.experimental-feature.tsignores remotes and env files, because it runs before the project is known.db.passwordhas no env tier.secrets settolerates an invalid unrelated value, so a broken key doesn't block rotating a secret.Behaviour changes
[remotes.*]block beatSUPABASE_*variables for the keys it setSUPABASE_PROJECT_IDand a matched remoteproject_idnamed local Docker resourcesSUPABASE_PROJECT_IDwins--include-seedandenabled = false[db.seed] enabled = falsewon--include-seed,--sql-pathsorSUPABASE_DB_SEED_ENABLED=trueoverride it.db pushstill seeds only with--include-seeddb pushanddb reset --linkedask before seeding a project that matched a[remotes.*]block, unless that block itself setsdb.seed.enabled = true.--yesorSUPABASE_YESconfirms. A non-interactive run without it exits 1 withSeedConsentRequiredErrorbefore applying anything--passwordwith--db-urlor--localdb push,db pull,db dumpanddb schema declarative generatemigration listandmigration repairnow also reject--local.migration squashtargets the local database unless you pass--linked, sosquash -pneeds--linked. An empty-p ""counts as not passedSUPABASE_DB_PASSWORDfor another projectdb diff --use-pg-delta=falsedb pull --use-pg-delta(hidden, deprecated)[db.migrations].schema_pathsaloneSUPABASE_EXPERIMENTAL_PGDELTA_ENABLED[experimental.pgdelta].enabledlike any other key, sofalseselects migra for the run.SUPABASE_EXPERIMENTAL_PG_DELTAstays ignoredSUPABASE_EXPERIMENTAL_STACKtook0/1only)true/false,1/0,t/fin any case. Anything else fails the commandstopandservices) withCliConfigValueError, naming the variable or file it came from.secrets setis the one exceptionenabled,SUPABASE_API_PORTinfunctions serve,SUPABASE_API_SCHEMASingen types --linked/^\d+$/in one reader, octal-aware in another0x,0o,0band_separators, max 65535. A leading zero (054322) is rejectedSUPABASE_REMOTES_<NAME>_PROJECT_IDdbcommands onlysecrets set,config diff,config pushand storagestartandfunctionsfell back to the project ref; the db readers used the folder namegen types --localpasswordSUPABASE_DB_PASSWORD[db].password, like every other--localcommandservices,functions deploy,functions download,functions serveconfig.tomlonly, in placesconfig.jsonfirst, like every other commandconfig pushandconfig diffSUPABASE_*and flag overrides and show the same values. Env-sourced rows are labelled, and JSON output carriesoriginlink --passwordNewly env-overridable keys
Four config keys had no
SUPABASE_*override before and now have one:auth.sms.otp_expiry(SUPABASE_AUTH_SMS_OTP_EXPIRY)auth.sms.otp_length(SUPABASE_AUTH_SMS_OTP_LENGTH)db.network_restrictions.allowed_cidrs(SUPABASE_DB_NETWORK_RESTRICTIONS_ALLOWED_CIDRS)db.network_restrictions.allowed_cidrs_v6(SUPABASE_DB_NETWORK_RESTRICTIONS_ALLOWED_CIDRS_V6)Error codes
MigrationPasswordFlagsErroris nowDbPasswordFlagsError.CliConfigValueErrorinstead ofDbConfigLoadError,SeedConfigLoadError,StatusConfigLoadErrororStopConfigLoadError.SeedConsentRequiredError.BREAKING CHANGE: Flags and
SUPABASE_*environment variables now override config, including a matched[remotes.<name>]block. Every value resolves in one order: flag > shell environment > project env files >config.json/config.toml(a matched remote block over the base) > default. Project env files are.env.<SUPABASE_ENV>.local,.env.local,.env.<SUPABASE_ENV>and.env, insupabase/and then the project root;SUPABASE_ENVdefaults todevelopment.[remotes.*]block, anySUPABASE_*variable in the job or in those files now beats the block. The CLI warns for each value it overrides. Checkenv | grep ^SUPABASE_in CI andgrep -h ^SUPABASE_ supabase/.env* .env*in the repo, and setSUPABASE_ENVin CI so.env.developmentdoesn't apply.supabase config pushnow pushes those overrides; for example, aSUPABASE_AUTH_SITE_URLin.env.localreplaces the value in[remotes.production]. Push labels each env-sourced value, andsupabase config diffshows the same values.[remotes.*]block now asks first, unless the block itself setsdb.seed.enabled = true.db push --include-seedanddb reset --linkedexit 1 in CI unless you pass--yes.--include-seedandSUPABASE_DB_SEED_ENABLED=truenow overrideenabled = falsein the base[db.seed]too.db pushstill seeds only with--include-seed.--passwordwith--localor--db-urlnow exits 1 ondb push,db pull,db dump,db schema declarative generate,migration listandmigration repair.migration squashtargets the local database by default, somigration squash -pneeds--linked. Put the password in the URL, or set[db].passwordfor the local database.SUPABASE_DB_PASSWORDis no longer sent to another project (--project-ref B). Pass--password, or provide an access token so the CLI can create a temporary login role.SUPABASE_*variable now fails every command that loads project config, includingdb push,stopandservices(for exampleSUPABASE_STUDIO_PORT=abc). The error names the variable or file and reportsCliConfigValueError.SUPABASE_EXPERIMENTAL_PGDELTA_ENABLEDoverrides[experimental.pgdelta].enabled, sofalseselects migra for the run. Boolean variables, includingSUPABASE_EXPERIMENTAL_STACK, accepttrue/false,1/0ort/fand fail on anything else.supabase db diff --use-pg-delta=falsenow turns pg-delta off even when config or env turns it on.supabase gen types --localuses[db].password, notSUPABASE_DB_PASSWORD.SUPABASE_PROJECT_IDnow names local containers even when a remote block matches. Without aproject_idin config.toml, local containers and volumes are named after the project folder, not the project ref. Runsupabase stopbefore upgrading, or setproject_id.054322) are rejected.servicesand thefunctionscommands readconfig.jsonbeforeconfig.toml.supabase link --passwordis deprecated and ignored.MigrationPasswordFlagsErroris nowDbPasswordFlagsError; invalid values reportCliConfigValueError; seeding without consent reportsSeedConsentRequiredError.