You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
make deploy failed twice on 2026-07-25 for reasons the Makefile could have caught itself, in
both cases after burning several minutes on a misleading error. Both are cheap to make
impossible. Documenting them (#79) helps whoever is already stuck; guarding them in the target
means nobody gets stuck.
Both guards belong to the same 14-line Makefile and the same deploy target, so they are one
issue and should be one PR — two PRs would collide on the same lines.
Guard 1 — missing token silently falls through to the wrong account
SUPABASE_ACCESS_TOKEN is loaded per-directory by direnv from .envrc. direnv does not fire
in a non-interactive shell, so any scripted or agent-driven make deploy runs with no token,
falls back to the personal account (SecondBrain org, no access to the project) and fails:
unexpected list functions status 403: Your account does not have the necessary privileges…
That message reads as a permissions problem with the account, not as a missing token — the
wrong diagnosis is the natural one.
Fix direction. Before deploying, if SUPABASE_ACCESS_TOKEN is unset and .envrc exists,
source it; if it is still unset, fail with a message naming the cause.
⚠️Implementation trap: each line of a make recipe runs in its own sub-shell, so source .envrc on one line and supabase functions deploy on the next will not share the
variable. Chain them in a single line (... && ...), or use .ONESHELL:. A fix that ignores
this will look right, pass review, and change nothing.
.envrc is gitignored and machine-specific, so the guard must degrade gracefully: an already-set SUPABASE_ACCESS_TOKEN (CI, another machine) must be honoured and .envrc never required to
exist.
Guard 2 — an old CLI dies at bundling, after auth has already succeeded
supabase/functions/hal-mcp/deno.lock is lockfile version 5 (since c19bec9, June 2026).
CLI 2.72.7 cannot read it and aborts after a successful auth, which makes the failure look
unrelated to tooling:
Error: Failed reading lockfile at '.../deno.lock'
Caused by: Unsupported lockfile version '5'. Try upgrading Deno or recreating the lockfile
The CLI's own suggestion — "recreating the lockfile" — is the wrong move here: deno.lock
pins the exact dependency versions that ship to production. Regenerating it to silence the error
would change what gets deployed. Upgrading the CLI is the fix (2.72.7 → 2.109.1 worked).
Fix direction. Fail fast with a minimum-version check before invoking the deploy, printing
the required version and the brew upgrade supabase remedy. sort -V is enough for the
comparison; no need to be clever. Note that Homebrew now also refuses untrusted taps
(brew trust --formula supabase/tap/supabase) — worth naming in the error message.
Acceptance
make deploy in a shell with no SUPABASE_ACCESS_TOKEN and no direnv either succeeds by
sourcing .envrc, or fails naming the missing token — never a bare 403.
An already-exported SUPABASE_ACCESS_TOKEN is used as-is; a missing .envrc is not an error
when the token is already set.
make deploy with a CLI below the minimum stops before bundling, with a message naming the
required version and the upgrade command.
Verified negatively for both guards: run with the token unset, and with an old CLI (or a
temporarily raised minimum), and confirm each stops with its own message.
Summary
make deployfailed twice on 2026-07-25 for reasons theMakefilecould have caught itself, inboth cases after burning several minutes on a misleading error. Both are cheap to make
impossible. Documenting them (#79) helps whoever is already stuck; guarding them in the target
means nobody gets stuck.
Both guards belong to the same 14-line
Makefileand the samedeploytarget, so they are oneissue and should be one PR — two PRs would collide on the same lines.
Guard 1 — missing token silently falls through to the wrong account
SUPABASE_ACCESS_TOKENis loaded per-directory bydirenvfrom.envrc. direnv does not firein a non-interactive shell, so any scripted or agent-driven
make deployruns with no token,falls back to the personal account (SecondBrain org, no access to the project) and fails:
That message reads as a permissions problem with the account, not as a missing token — the
wrong diagnosis is the natural one.
Fix direction. Before deploying, if
SUPABASE_ACCESS_TOKENis unset and.envrcexists,source it; if it is still unset, fail with a message naming the cause.
source .envrcon one line andsupabase functions deployon the next will not share thevariable. Chain them in a single line (
... && ...), or use.ONESHELL:. A fix that ignoresthis will look right, pass review, and change nothing.
.envrcis gitignored and machine-specific, so the guard must degrade gracefully: an already-setSUPABASE_ACCESS_TOKEN(CI, another machine) must be honoured and.envrcnever required toexist.
Guard 2 — an old CLI dies at bundling, after auth has already succeeded
supabase/functions/hal-mcp/deno.lockis lockfile version 5 (sincec19bec9, June 2026).CLI 2.72.7 cannot read it and aborts after a successful auth, which makes the failure look
unrelated to tooling:
The CLI's own suggestion — "recreating the lockfile" — is the wrong move here:
deno.lockpins the exact dependency versions that ship to production. Regenerating it to silence the error
would change what gets deployed. Upgrading the CLI is the fix (2.72.7 → 2.109.1 worked).
Fix direction. Fail fast with a minimum-version check before invoking the deploy, printing
the required version and the
brew upgrade supabaseremedy.sort -Vis enough for thecomparison; no need to be clever. Note that Homebrew now also refuses untrusted taps
(
brew trust --formula supabase/tap/supabase) — worth naming in the error message.Acceptance
make deployin a shell with noSUPABASE_ACCESS_TOKENand no direnv either succeeds bysourcing
.envrc, or fails naming the missing token — never a bare 403.SUPABASE_ACCESS_TOKENis used as-is; a missing.envrcis not an errorwhen the token is already set.
make deploywith a CLI below the minimum stops before bundling, with a message naming therequired version and the upgrade command.
temporarily raised minimum), and confirm each stops with its own message.
docs/operations.md§2 updated so the prose and the guards do not disagree — see docs(operations): deploy prerequisites learned the hard way #79, whichdocuments these same two obstacles and should be reconciled, not duplicated.
Related
operations.md(the diagnostic half of the same problem)hal-mcpunit tests