Skip to content

fix(cli): secrets set tolerates a malformed config.toml (Go parity)#5796

Merged
Coly010 merged 17 commits into
developfrom
columferry/cli-1867-secrets-set-tolerate-malformed-configtoml-instead-of
Jul 7, 2026
Merged

fix(cli): secrets set tolerates a malformed config.toml (Go parity)#5796
Coly010 merged 17 commits into
developfrom
columferry/cli-1867-secrets-set-tolerate-malformed-configtoml-instead-of

Conversation

@Coly010

@Coly010 Coly010 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Current Behavior

Go's secrets set (internal/secrets/set/set.go:20-24) swallows a malformed supabase/config.toml parse error to the debug logger and proceeds with empty EdgeRuntime.Secrets — env-file and positional-arg secrets still apply. secrets set has no --linked/--local/--db-url flag, so the root PreRun never loads the config first either; this is the only load. The TS port instead let the parse error propagate as a fatal LegacySecretsConfigParseError, aborting the whole command even when the user only wanted to set a secret via CLI arg or env-file.

Expected Behavior

  • Catches ProjectConfigParseError, logs it to the debug logger, and continues with no config-declared secrets, matching Go.
  • The logged message is truncated before any blank-line-separated source snippet: smol-toml's TomlError (and some schema-decode errors) embed a codeblock of the surrounding file lines in their message, which for this file's [edge_runtime.secrets] section can include literal secret values. Go's equivalent log line (DecodeError.Error()) is a short, content-free message — its verbose .String() with the snippet is never called by set.go. Truncating avoids echoing a user's own secret value into --debug output next to an unrelated syntax error.
  • Deletes the now-unused LegacySecretsConfigParseError (no remaining references).
  • Threads LegacyDebugLogger into the shared legacyManagementApiRuntimeLayer (used by many legacy commands) since the layer was already building the same instance internally for cliConfig/httpClient/credentials but never exposed it at the top level — the file's own doc comment describes this as the sanctioned way to add a new commonly-needed top-level service.

Fixes CLI-1867

## Current Behavior

Go's `secrets set` (`internal/secrets/set/set.go:20-24`) swallows a
malformed `supabase/config.toml` parse error to the debug logger and
proceeds with empty `EdgeRuntime.Secrets` — env-file and positional-arg
secrets still apply. `secrets set` has no `--linked`/`--local`/`--db-url`
flag, so the root PreRun never loads the config first either; this is
the only load. The TS port instead let the parse error propagate as a
fatal `LegacySecretsConfigParseError`, aborting the whole command even
when the user only wanted to set a secret via CLI arg or env-file.

## Expected Behavior

- Catches `ProjectConfigParseError`, logs it to the debug logger, and
  continues with no config-declared secrets, matching Go.
- The logged message is truncated before any blank-line-separated
  source snippet: `smol-toml`'s `TomlError` (and some schema-decode
  errors) embed a codeblock of the surrounding file lines in their
  message, which for this file's `[edge_runtime.secrets]` section can
  include literal secret values. Go's equivalent log line
  (`DecodeError.Error()`) is a short, content-free message — its
  verbose `.String()` with the snippet is never called by `set.go`.
  Truncating avoids echoing a user's own secret value into `--debug`
  output next to an unrelated syntax error.
- Deletes the now-unused `LegacySecretsConfigParseError` (no remaining
  references).
- Threads `LegacyDebugLogger` into the shared
  `legacyManagementApiRuntimeLayer` (used by many legacy commands)
  since the layer was already building the same instance internally
  for `cliConfig`/`httpClient`/`credentials` but never exposed it at
  the top level — the file's own doc comment describes this as the
  sanctioned way to add a new commonly-needed top-level service.

Fixes CLI-1867
@Coly010

Coly010 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 923815ff72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts Outdated
…ors (review: #5796)

Go's viper+mapstructure decode (pkg/config/config.go:749) mutates the
target struct field-by-field, so a type error on an unrelated key (e.g.
analytics.port) doesn't stop EdgeRuntime.Secrets from landing on
utils.Config — confirmed empirically against pkg/config. Effect
Schema.decodeUnknownSync is all-or-nothing, so `secrets set` was
silently discarding a valid [edge_runtime.secrets] section whenever
any other field in config.toml failed schema decode.

ProjectConfigParseError now carries the pre-decode document when the
failure is a schema-decode error (not a raw parse error) so secrets
set can re-decode just the edge_runtime subtree against the full
schema and recover its secrets, without loosening decode semantics
for other @supabase/config callers. A genuine parse failure still has
no recoverable structure in either implementation.
@Coly010

Coly010 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

1 similar comment
@Coly010

Coly010 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19dc72c044

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts Outdated
Coly010 added 2 commits July 6, 2026 19:00
… (review: #5796)

Re-decoding the whole edge_runtime subtree still failed recovery when the
schema error came from a sibling field in the same table (e.g.
edge_runtime.inspector_port), discarding a valid [edge_runtime.secrets]
block. Verified against pkg/config directly that Go's mapstructure decode
tolerates this case and still populates EdgeRuntime.Secrets, so
recoverEdgeRuntimeConfig now re-slices just edge_runtime.secrets instead of
the whole edge_runtime table.
The previous commit's cast (`edgeRuntime as Record<string, unknown>`)
violates this repo's no-`as`-casts policy; a local `isRecord` type
predicate narrows `unknown` without it. Also fixes an oxfmt formatting
drift in SIDE_EFFECTS.md left over from an earlier commit in this PR.
@Coly010

Coly010 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: a2b843d298

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Coly010 Coly010 marked this pull request as ready for review July 7, 2026 10:13
@Coly010 Coly010 requested a review from a team as a code owner July 7, 2026 10:13
@Coly010 Coly010 self-assigned this Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@3153365d1d092a739b2d68b1a00fc9b76aaee6cb

Preview package for commit 3153365.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2b843d298

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Comment thread packages/config/src/io.ts Outdated
Coly010 added 3 commits July 7, 2026 11:43
…only (review: #5796)

Several callers of loadProjectConfig (gen types, next start, functions
dev/serve/deploy) don't catch ProjectConfigParseError, so the attached
document propagates uncaught. Only secrets set's recoverEdgeRuntimeConfig
reads it, and only edge_runtime.secrets, so attaching the whole
post-interpolation document (including literal edge_runtime.secrets
values) is unnecessary blast radius for a TS-only telemetry surface with
no Go equivalent to weigh against.
…5796)

Regression test for a mixed valid/invalid edge_runtime.secrets map
(GOOD = "ok" alongside BAD = 123). recoverEdgeRuntimeConfig's per-entry
filtering (landed alongside the ProjectConfigParseError.document
narrowing) now keeps GOOD instead of discarding the whole map, matching
Go's mapstructure map decode which decodes each entry independently.
…review: #5796)

loadProjectConfig resolves env(VAR) references against .env/.env.local
before schema decode, so a malformed dotenv line fails with
ProjectEnvParseError rather than ProjectConfigParseError, escaping the
existing catchTag and aborting the command. Go's Load() (pkg/config/config.go:788-791)
calls loadNestedEnv first too and swallows any resulting error the same
way internal/secrets/set/set.go swallows a bad config.toml, so secrets
set must stay non-fatal here as well and keep working from env-file/positional
args.

@jgoux jgoux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found three remaining issues in the current head. The first two are Go-parity behavior gaps in secrets set; the third is a sensitive-data hardening issue in the config error shape.

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Comment thread packages/config/src/io.ts Outdated
…ocument (review: #5796)

Several loadProjectConfig callers (gen types, next start, functions
dev/serve/deploy) don't catch ProjectConfigParseError, so its document
field can propagate uncaught. Wrap edge_runtime.secrets values in
Redacted before attaching, matching the x-secret treatment secret()
already gets elsewhere in this package, so an uncaught error can't
carry a resolved secret in plaintext. secrets set's
recoverEdgeRuntimeConfig/filterDecodableSecrets unwrap via
Redacted.value before re-decoding.
@Coly010

Coly010 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f58020207

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts Outdated
Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Coly010 added 2 commits July 7, 2026 12:48
…s (review: #5796)

isRecord() treated arrays as records, so `[edge_runtime] secrets = [...]`
fell through filterDecodableSecrets and Object.entries turned array
indices into fabricated secret names (e.g. "0"). Go's mapstructure never
sets WeaklyTypedInput, so a slice source for a map-typed field hits
UnconvertibleTypeError and the whole field is left empty instead.
…eview: #5796)

loadProjectConfig() omitted { projectRef: ref }, so a schema-decode
recovery on `secrets set --project-ref <ref>` used the base
[edge_runtime.secrets] instead of a matching [remotes.*] override. Go
seeds Config.ProjectId before Load() and merges the override in
loadFromFile before mapstructure ever runs, so the recovery must load
against the same resolved ref. Also swallow DuplicateRemoteProjectIdError
non-fatally, matching Go's LoadConfig catch-all.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ff3823e87

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/config/src/io.ts Outdated
Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Coly010 added 2 commits July 7, 2026 13:16
…5796)

Codex flagged that redactEdgeRuntimeSecrets only wrapped string secret
values in Redacted before attaching them to ProjectConfigParseError.document,
so a malformed entry with a non-string shape (e.g. a TOML array or inline
table) still carried the secret in plaintext. Redacted.make accepts any
value and always stringifies to <redacted:...>, so wrap every entry
unconditionally instead of gating on typeof.
…ew: #5796)

Go's DecryptSecretHookFunc (pkg/config/secret.go:98) never hashes an empty
secret value, and ListSecrets (internal/secrets/set/set.go:48-52) only
includes entries with a non-empty SHA256, so an empty config-declared
secret is never sent and can't overwrite a same-named remote secret with
an empty string. The TS merge loop only checked Redacted.isRedacted, which
missed the empty-value case for both the happy-path config load and the
malformed-config recovery path (both flow through the same loop). Require
a non-empty value too so both of Go's zero-hash cases match.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: de9c5ffcf9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts Outdated
Comment thread packages/config/src/io.ts Outdated
…rrors (review: #5796)

`redactEdgeRuntimeSecrets` only wrapped per-entry values inside an
`edge_runtime.secrets` table; a malformed `secrets` field that is itself
non-object (e.g. `secrets = ["actual-secret"]`) fell through its early
return and reached `ProjectConfigParseError.document` unredacted. Wrap
the whole field in `Redacted` in that case too, and unwrap it in
`secrets set`'s `recoverEdgeRuntimeConfig` before the `isRecord` check
so the wrapper object itself isn't misread as a one-entry secrets map.
…rrors (review: #5796)

`secrets set --debug` stringified the raw schema-decode error when a
malformed `[edge_runtime.secrets]` entry failed decode, which embeds
the rejected value inline (e.g. `Expected string, actual
["actual-secret"]`) with no blank-line separator for the existing
truncation to catch. Go's pinned mapstructure decode-error types never
include the rejected value, only type names, so use a fixed message
for schema-decode failures and keep the truncation for genuine TOML
syntax errors, where it already matches Go.
@Coly010

Coly010 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75e09e27c2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts Outdated
Go's loadFromFile prints "Loading config override: [remotes.<name>]" to
stderr unconditionally when a [remotes.*] block matches the resolved ref
(pkg/config/config.go:605), before mapstructure decode ever runs. The
ref-aware loadProjectConfig call added to secrets set mapped the loaded
result straight down to .config, discarding appliedRemote and silently
dropping the notice for remote-specific configs, unlike config push and
the storage/seed handlers which already surface it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7cbf5f303d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/secrets/set/set.handler.ts
Coly010 added 2 commits July 7, 2026 15:04
…crets set (review: #5796)

Go's loadFromFile prints "Loading config override: [remotes.<name>]" to
stderr before mapstructure decode runs, so the notice still fires even
when the subsequent decode fails and secrets set recovers non-fatally.
ProjectConfigParseError now carries appliedRemote through the failed
decode so the catch path can surface it, matching the success path.
@Coly010

Coly010 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Coly010

Coly010 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Coly010 Coly010 added this pull request to the merge queue Jul 7, 2026
Merged via the queue into develop with commit 149fd49 Jul 7, 2026
20 checks passed
@Coly010 Coly010 deleted the columferry/cli-1867-secrets-set-tolerate-malformed-configtoml-instead-of branch July 7, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants