Tool pages / Supabase CLI

Supabase CLI 2.120.0: latest version, breaking changes and gotchas

Latest: Supabase CLI 2.120.0, released (release notes).

Last verified 2026-10-07 against 2.120.0. Page updated . Also as Markdown and JSON.

The latest Supabase CLI (supabase, npm supabase) is 2.120.0, released 2026-10-06 16:40 UTC. Upgrade with npm i -D supabase@latest (or npm i -g supabase@latest, brew upgrade supabase/tap/supabase). Its 168 default help pages are identical to 2.119.0 in our sandbox diff; the changes sit in the experimental supabase stack commands (stack logs --follow, --tail, --since). What breaks agent scripts: command flags must follow the subcommand since 2.100.0, detected coding agents get JSON output and JSON errors since 2.106.0, and unattended config push skips changes without --yes since 2.118.0.

How do I install or upgrade to Supabase CLI 2.120.0?

npm, as a project dev dependency (the README's npm method):

npm i -D supabase@latest
npx supabase --version   # 2.120.0

npm, global (works from 2.99.0; 2.98.2 and older refuse):

npm i -g supabase@latest

Homebrew (the supabase/tap formula is the one the README calls always up to date):

brew upgrade supabase/tap/supabase

Scoop (Windows):

scoop update supabase

Install script (macOS, Linux):

curl -fsSL https://raw.githubusercontent.com/supabase/cli/main/install | bash

Beta channel (2.121.0-beta.7 on 2026-10-07):

npm i -D supabase@beta

Pin the last Go CLI (accepts command flags before the subcommand):

npm i -D supabase@2.98.2

Supabase CLI key facts

What changed in the last 5 Supabase CLI releases?

Supabase CLI 2.120.0 (2026-10-06 16:40 UTC)

  • Service logs persist under <stateRoot>/<stackId>/logs/; supabase stack logs prints retained history and gains -f/--follow, --tail and --since. (source)
  • Opt-in tracing: SUPABASE_TRACE_FILE writes a JSON trace of one run, SUPABASE_OTLP_ENDPOINT streams to an OTLP collector. (source)
  • Every --stack-id flag accepts the 8-character ID from stack list or any unique prefix of 4+ characters. (source)
  • The upgrade check is cached in ~/.supabase/cli-latest for 10 hours outside projects and for --version. (source)
  • supabase start prints API_URL, FUNCTIONS_URL and MCP_URL even when [api] enabled = false. (source)

Supabase CLI 2.119.0 (2026-09-30 21:35 UTC)

  • OrioleDB configuration graduates: experimental_oriole becomes oriole. (source)
  • Studio's MCP server is served at <API_URL>/mcp on the stack's API listener. (source)
  • Resumable uploads and S3 endpoints work through the gateway on Docker Desktop for macOS. (source)
  • Stack connection details (database URL, MCP endpoint) print on start and status. (source)

Supabase CLI 2.118.0 (2026-09-25 13:23 UTC)

  • New supabase pull: config, migration history, schema and Edge Function sources from a linked project in one step. (source)
  • Experimental supabase stack start|stop|status|list|logs|prepare|restart|destroy. (source)
  • Breaking for CI: unattended config push skips changes without an affirmative answer or --yes/SUPABASE_YES. (source)
  • An explicit --workdir is used as given and no longer climbs to a parent project. (source)
  • storage rm fails without explicit confirmation. (source)

Supabase CLI 2.117.0 (2026-09-07 16:47 UTC)

  • New supabase config diff (and config pull) to preview and fetch remote project config. (source)
  • @supabase/config published to npm for programmatic config validation and diffing. (source)
  • Experimental Workers commands (new, list, status, delete, push, logs). (source)
  • Shadow-database baseline cache is on by default; --no-cache-baseline turns it off. (source)

Supabase CLI 2.116.0 (2026-08-26 19:51 UTC)

  • [api].auto_expose_new_tables defaults to true again when unset, reverting 2.106.0; the planned 2026-10-30 removal was dropped. (source)
  • supabase start and stop are about 10 seconds faster. (source)
  • Shadow database baseline cached as a PGDATA snapshot for faster repeated diffs. (source)
  • New [workers] section in supabase/config.toml. (source)

Which Supabase CLI commands and flags were added or removed?

Supabase CLI 2.119.0 → 2.120.0

Default surface: 0 commands added, 0 removed, 0 help pages changed. Gated supabase stack surface: 1 command with flags added, 7 help pages changed.

Method: bin/tool-snapshot ran --help for every supabase subcommand of both versions in a throwaway Linux sandbox (168 and 168 help pages), then bin/tool-diff compared them. supabase stack is hidden unless the project config enables it, so we also ran supabase stack <sub> --help for both versions in a project created with SUPABASE_EXPERIMENTAL_STACK=1 supabase init and diffed that (tools/supabase/diffs/2.119.0..2.120.0-stack.diff). Hidden flags do not appear in --help.

CommandFlags addedFlags removed
supabase stack logs--follow--since--tailnone
  • supabase stack logs changed meaning: 2.119.0 "Stream live logs until interrupted; retained history is unavailable."; 2.120.0 "Print retained service logs and exit; with --follow, keep streaming new lines." A script that relied on it blocking now gets history and exits.
  • Every --stack-id help line changes from "by id" to "by id or unique id prefix".
  • Our default capture sets SUPABASE_NO_UPDATE_NOTIFIER=1. Without it, an older version appends "A new version of Supabase CLI is available" after every help page, which makes every page differ.

Supabase CLI 2.117.0 → 2.118.0

8 commands added, 0 removed, 0 commands with flags added or removed; 160 help pages changed in any way.

Method: bin/tool-snapshot ran --help for every supabase subcommand of both versions in a throwaway Linux sandbox (160 and 168 help pages), then bin/tool-diff compared them. Hidden flags do not appear in --help.

Commands added:

  • supabase feedback
  • supabase feedback add
  • supabase feedback delete
  • supabase notebooks
  • supabase notebooks pull
  • supabase notebooks push
  • supabase pull
  • supabase whoami
  • All 160 pages changed because the global --workdir text changed to "used exactly as given, with no ancestor directory search".
  • supabase config push --help 2.117.0: "a non-interactive run (no TTY, --yes, or piped stdin with no answer) defaults to proceeding"; 2.118.0: "Non-interactive runs honor piped y/n answers and skip changes without an affirmative answer or --yes/SUPABASE_YES."

What breaks when upgrading Supabase CLI, and how do I migrate?

VersionChangeMigration
2.118.0Unattended supabase config push (no TTY, JSON output or piped stdin) skips each change unless it gets an affirmative answer or --yes/SUPABASE_YES; before, it proceeded by default.Add --yes (or SUPABASE_YES=1) to CI steps that must apply config, and run supabase config diff first to review.
2.118.0An explicit --workdir is used exactly as given and no longer searches parent directories for supabase/.Point --workdir at the directory that contains supabase/.
2.116.0[api].auto_expose_new_tables unset means true again (auto-expose new public tables), reverting 2.106.0; the deprecation and 2026-10-30 removal were withdrawn.Nothing to do for new setups. Local volumes created under 2.106.0 to 2.115.0 keep their revoked grants until supabase db reset. Set false explicitly to keep the revoke behaviour.
2.115.0db diff, db pull and declarative schema commands use the bundled pg-delta engine; output can differ. supabase test db exits non-zero with no pgTAP tests found in <paths> when no tests run. --password beats SUPABASE_DB_PASSWORD on db remote.Review generated SQL; move declarative files to supabase/schemas or set declarative_schema_path; SUPABASE_USE_PG_DELTA_NEXT=false was announced as a temporary opt-out. Drop test db steps that run zero tests.
2.112.0functions deploy no longer forwards NPM_AUTH_TOKEN into Docker bundling. db diff --use-pg-schema and db pull --experimental are deprecated.Inline the token in .npmrc or deploy with --use-api; use db pull --declarative.
2.106.0A detected coding agent (or --agent yes) gets JSON output by default; errors become a JSON envelope on stdout with a non-zero exit.Parse stdout as JSON in agent runs, or pass --agent no / --output-format text to keep text.
2.100.0The TypeScript CLI's parser rejects command flags placed before the subcommand (Unrecognized flag or Unknown subcommand).supabase network-restrictions --project-ref X get → supabase network-restrictions get --project-ref X. Global flags can stay anywhere.

What Supabase CLI errors did we reproduce, and how do I fix them?

A command flag before the subcommand fails with `Unrecognized flag` (Supabase CLI 2.120.0)

supabase network-restrictions --project-ref abcdefghijklmnopqrst get
[… stderr starts with the `supabase network-restrictions` help page; trimmed 27 lines …]
Unrecognized flag: --project-ref in command supabase network-restrictions

  Hint: --project-ref is available on `supabase network-restrictions get` and `supabase network-restrictions update`. Pass it after the subcommand, for example:
    supabase network-restrictions get --project-ref <value>
Try rerunning the command with --debug to troubleshoot the error.
# exit 1. 2.98.2 (Go CLI) accepted the same order and went on to: must set the --experimental flag to run this command

Fix: Put command flags after the subcommand: supabase network-restrictions get --project-ref <ref>. Global flags (--experimental, --debug, --yes, --workdir, --profile, --output-format) may stay anywhere. (source)

Under a coding agent, errors are JSON on stdout (Supabase CLI 2.120.0)

CLAUDECODE=1 supabase network-restrictions get --project-ref abcdefghijklmnopqrst
{"_tag":"Error","error":{"code":"ExperimentalRequiredError","message":"must set the --experimental flag to run this command"}}
# exit 1. Without CLAUDECODE=1, or with --agent no, the same run prints on stderr:
must set the --experimental flag to run this command
Try rerunning the command with --debug to troubleshoot the error.

Fix: Read stdout as JSON and check error.code, or pass --agent no (or --output-format text) for text. --help and --version stay text either way. Note that network-restrictions also needs --experimental. (source)

`supabase stack` is "Unknown subcommand" until the project enables it (Supabase CLI 2.120.0)

supabase stack list
[… stderr starts with the root help page; trimmed 65 lines …]
Unknown subcommand "stack" for "supabase"

  Did you mean this?
    start
Try rerunning the command with --debug to troubleshoot the error.
# exit 1. `supabase stack --help` and `supabase --experimental stack --help` print the root help and exit 0.

Fix: Create the project with SUPABASE_EXPERIMENTAL_STACK=1 supabase init, or add [experimental] stack = true to supabase/config.toml. Then supabase stack list printed No managed stacks found. (exit 0). The global --experimental flag does not unlock it. (source)

`supabase start` without Docker or Podman (Supabase CLI 2.120.0)

supabase init --yes && supabase start
failed to inspect container health: docker: command not found (podman also not found) — install Docker Desktop or Podman and ensure it is on PATH
Try rerunning the command with --debug to troubleshoot the error.
# exit 1. With CLAUDECODE=1 the same error is on stdout:
{"_tag":"Error","error":{"code":"DockerLifecycleInspectError","message":"failed to inspect container health: docker: command not found (podman also not found) — install Docker Desktop or Podman and ensure it is on PATH"}}

Fix: Install and start Docker or Podman. The experimental stack can run natively on Linux x64/arm64 and macOS arm64 (supabase stack start --runtime native), but see the next gotcha. (source)

The native stack refuses to run PostgreSQL as root (Supabase CLI 2.120.0)

SUPABASE_EXPERIMENTAL_STACK=1 supabase init --yes && supabase stack start   # as root, no Docker
PostgreSQL cannot be run as root
Set SUPABASE_NATIVE_POSTGRES_USER=<user> to run PostgreSQL as a non-root user, creating one if needed (on Linux, for example `useradd --system --user-group supabase-postgres`).
# exit 1. With useradd + SUPABASE_NATIVE_POSTGRES_USER=supabase-postgres, our container stopped 79 s later at:
/ must be owned and writable only by root to run PostgreSQL as 'supabase-postgres'

Fix: Run as a normal user, or create a system user and set SUPABASE_NATIVE_POSTGRES_USER. Containers whose / is not root-owned and writable only by root fail the second check; we did not get past it in our sandbox, so use Docker there. (source)

`npm i -g supabase` fails on 2.98.2 and older (Supabase CLI 2.98.2)

npm i -g supabase@2.98.2
npm error Installing Supabase CLI as a global module is not supported.
npm error Please use one of the supported package managers: https://github.com/supabase/cli#install-the-cli
# exit 1

Fix: Upgrade: npm i -g supabase@2.99.0 and later installed and ran in our sandbox. For a pinned old version, install it per project (npm i -D supabase@2.98.2, then npx supabase). (source)

`db pull --experimental` is deprecated (Supabase CLI 2.120.0)

supabase db pull --experimental
The --experimental structured-dump mode for `db pull` is deprecated and will be removed in a future release. Use --declarative instead to pull the remote schema as per-object files.
Cannot find project ref. Have you run supabase link?
Try rerunning the command with --debug to troubleshoot the error.
# exit 1 (unlinked project; we did not log in)

Fix: Use supabase db pull --declarative. (source)

`supabase test db` with no local database running (Supabase CLI 2.120.0)

supabase test db
Connecting to local database...
failed to connect to postgres: failed to connect to `host=127.0.0.1 user=postgres database=postgres`: dial error (connect ECONNREFUSED 127.0.0.1:54322)
Make sure Docker is running, then run: supabase start
# exit 1

Fix: Run supabase start first. Since 2.115.0 a run that finds zero pgTAP tests also exits non-zero (no pgTAP tests found in <paths>). (source)

Supabase CLI release history by month

2026-10: 2.120.0 (1 stable release to 2026-10-07; 2.121.0 in beta)

  • 2.120.0: persisted stack logs with --follow/--tail/--since, OTLP tracing, short stack IDs. (source)

2026-09: 2.117.0 to 2.119.0 (3 releases)

  • 2.117.0 added config diff and config pull and published @supabase/config. (source)
  • 2.118.0 added pull, whoami, notebooks and the experimental stack commands; unattended config push now needs --yes. (source)
  • 2.119.0 made OrioleDB config stable and served Studio's MCP server at /mcp. (source)

2026-08: 2.112.0 to 2.116.0 (5 releases)

  • 2.112.0 stopped forwarding NPM_AUTH_TOKEN to Docker bundling and deprecated db pull --experimental. (source)
  • 2.115.0 made pg-delta the default diff engine and made test db fail on zero tests. (source)
  • 2.116.0 restored auto_expose_new_tables = true as the default. (source)

2026-07: 2.109.1 to 2.111.0 (3 releases)

  • 2.109.1 fixed db pull hanging in non-interactive mode. (source)
  • 2.110.0: supabase start recovers a stopped database; API keys redacted from errors. (source)

2026-06: 2.103.0 to 2.109.0 (7 releases)

  • 2.106.0 defaulted detected coding agents to JSON output and (until 2.116.0) stopped auto-exposing new tables. (source)
  • 2.107.0 enabled pg-delta by default for new projects. (source)

2026-05: 2.98.1 to 2.102.0 (7 releases)

  • 2.99.0 (2026-05-18) shipped the TypeScript CLI shell with per-platform npm packages. (source)
  • 2.100.0 made command flags before the subcommand an error. (source)

Sources

Last verified: 2026-10-07.