fix: handle SecretVar JSON objects without value field in UnmarshalJSON - #4723
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughSummary by CodeRabbit
Walkthrough
ChangesSecretVar JSON parsing
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.12.2)level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies" Comment |
This stack of pull requests is managed by Graphite. Learn more about stacking. |
SecretVar JSON objects without value field in UnmarshalJSON
There was a problem hiding this comment.
🧹 Nitpick comments (1)
core/schemas/secretvar_test.go (1)
117-132: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a whitespace-prefixed object case.
SecretVar.UnmarshalJSONnow trims leading whitespace before deciding whether to take the compat-object path, but this new subtest still starts with{, so the new guard itself never gets exercised.Suggested addition
t.Run("from_env without value field", func(t *testing.T) { input := `{"env_var":"MY_KEY","from_env":true}` var sv SecretVar if err := sv.UnmarshalJSON([]byte(input)); err != nil { t.Fatalf("UnmarshalJSON failed: %v", err) } if sv.GetRawRef() != "env.MY_KEY" { t.Errorf("expected ref %q, got %q", "env.MY_KEY", sv.GetRawRef()) } if !sv.IsFromSecret() { t.Error("expected IsFromSecret=true") } if sv.Val != "resolved-value" { t.Errorf("expected Val=%q, got %q", "resolved-value", sv.Val) } }) + + t.Run("from_env without value field with leading whitespace", func(t *testing.T) { + input := " \n\t" + `{"env_var":"MY_KEY","from_env":true}` + var sv SecretVar + if err := sv.UnmarshalJSON([]byte(input)); err != nil { + t.Fatalf("UnmarshalJSON failed: %v", err) + } + if sv.GetRawRef() != "env.MY_KEY" { + t.Errorf("expected ref %q, got %q", "env.MY_KEY", sv.GetRawRef()) + } + if !sv.IsFromSecret() { + t.Error("expected IsFromSecret=true") + } + if sv.Val != "resolved-value" { + t.Errorf("expected Val=%q, got %q", "resolved-value", sv.Val) + } + })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/schemas/secretvar_test.go` around lines 117 - 132, The new whitespace-trimming branch in SecretVar.UnmarshalJSON is not covered by the current compat-object test because the input starts directly with an object brace. Update the SecretVar.UnmarshalJSON test in secretvar_test.go by adding a subtest that uses leading whitespace before the JSON object, and verify the same env-based resolution behavior through GetRawRef, IsFromSecret, and Val so the trim-before-compat-object path is actually exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@core/schemas/secretvar_test.go`:
- Around line 117-132: The new whitespace-trimming branch in
SecretVar.UnmarshalJSON is not covered by the current compat-object test because
the input starts directly with an object brace. Update the
SecretVar.UnmarshalJSON test in secretvar_test.go by adding a subtest that uses
leading whitespace before the JSON object, and verify the same env-based
resolution behavior through GetRawRef, IsFromSecret, and Val so the
trim-before-compat-object path is actually exercised.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7ddbb647-c10e-413d-a7ef-bd9649513d3d
📒 Files selected for processing (2)
core/schemas/secretvar.gocore/schemas/secretvar_test.go
56077d1 to
f7128a9
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/schemas/secretvar.go (1)
50-61: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUse the unquoted candidate consistently in
NewSecretVar.Line 51 checks
valafterstrconv.Unquote, but Line 61 still unmarshalsvalue. That means a quoted secret object string can pass the new{guard and still miss the compat path becausesonic.Unmarshalsees a JSON string, not the unquoted object payload.Suggested fix
- if sonic.Valid([]byte(value)) { - if trimmed := bytes.TrimSpace([]byte(val)); len(trimmed) > 0 && trimmed[0] == '{' { + candidate := []byte(val) + if sonic.Valid(candidate) { + if trimmed := bytes.TrimSpace(candidate); len(trimmed) > 0 && trimmed[0] == '{' { type secretVarCompat struct { Val string `json:"value"` Ref string `json:"ref"` SecretType SecretType `json:"type"` @@ - if err := sonic.Unmarshal([]byte(value), &raw); err == nil { + if err := sonic.Unmarshal(candidate, &raw); err == nil {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@core/schemas/secretvar.go` around lines 50 - 61, In NewSecretVar, the compat JSON-object check and unmarshal must both use the same unquoted candidate value. Update the logic around the trimmed `{` guard so it consistently operates on the unquoted string (the same value checked after strconv.Unquote) instead of mixing val and value, and ensure the sonic.Unmarshal call parses that unquoted payload. Keep the backward-compat handling in the secretVarCompat path intact while making the candidate selection consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@core/schemas/secretvar.go`:
- Around line 50-61: In NewSecretVar, the compat JSON-object check and unmarshal
must both use the same unquoted candidate value. Update the logic around the
trimmed `{` guard so it consistently operates on the unquoted string (the same
value checked after strconv.Unquote) instead of mixing val and value, and ensure
the sonic.Unmarshal call parses that unquoted payload. Keep the backward-compat
handling in the secretVarCompat path intact while making the candidate selection
consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 47b7e333-a2e7-4361-86e9-eff767e5f2fd
📒 Files selected for processing (2)
core/schemas/secretvar.gocore/schemas/secretvar_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- core/schemas/secretvar_test.go
|
Fixes #4319 |
The merge-base changed after approval.
f7128a9 to
f111e1c
Compare
The merge-base changed after approval.
f111e1c to
77c2e80
Compare
## Summary Briefly explain the purpose of this PR and the problem it solves. ## Changes - What was changed and why - Any notable design decisions or trade-offs ## Type of change - [ ] Bug fix - [ ] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Describe the steps to validate this change. Include commands and expected outcomes. ```sh # Core/Transports go version go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` If adding new configs or environment variables, document them here. ## Screenshots/Recordings If UI changes, add before/after screenshots or short clips. ## Breaking changes - [ ] Yes - [ ] No If yes, describe impact and migration instructions. ## Related issues Link related issues and discussions. Example: Closes #123 ## Security considerations Note any security implications (auth, secrets, PII, sandboxing, etc.). ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
* origin/dev: (79 commits) chore: add `helm-update` Claude skill for syncing Helm chart with `config.schema.json` (maximhq#5144) fix: web search options to google search mapping in gemini api (maximhq#5139) feat: add `postgresql.external.port` string support and `bifrost.mcp.toolGroups[*].id` to Helm chart (maximhq#5143) fix: parse `SecretVar` JSON with `ref`/`env_var` fields even when `value` is absent (maximhq#5146) Revert "fix: less strict unmarshalling for secret var (maximhq#4723)" (maximhq#5145) fix: max reasoning effort in openai (maximhq#5130) chore: replace manual `helm registry login` steps with `step-security/docker-login-action` (maximhq#5132) fix: support GA transcription-type sessions in POST /v1/realtime/client_secrets (maximhq#5092) community: add Xquik to MCP library (maximhq#5069) fix: warn callers not to truncate the #t= temp-token fragment on MCP inline-auth links (maximhq#5104) chore: build fix in core (maximhq#5129) fix: never persist masked provider key previews (maximhq#5106) Filter out provider-level keys from selector in prompt manager (maximhq#5018) fix: show user popover when `userInfo` exists and include `preferred_username` as display name fallback (maximhq#5098) fix: use `AutoMigrate` and add `runner_id`/`created_by_user_id` columns to sidekiq table migration (maximhq#5085) dds new harness skill and updates based on merged PRs (maximhq#5126) dds new harness skill and updates based on merged PRs (maximhq#5123) Add Trendshift badge to README (maximhq#5124) fix: make tracing span lookup nil-safe to prevent panic on streaming errors (maximhq#4896) Revert "fix: synthesize per-query rerank usage for Bedrock and Vertex (maximhq#4322)" (maximhq#5122) ...
## Summary Briefly explain the purpose of this PR and the problem it solves. ## Changes - What was changed and why - Any notable design decisions or trade-offs ## Type of change - [ ] Bug fix - [ ] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Describe the steps to validate this change. Include commands and expected outcomes. ```sh # Core/Transports go version go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` If adding new configs or environment variables, document them here. ## Screenshots/Recordings If UI changes, add before/after screenshots or short clips. ## Breaking changes - [ ] Yes - [ ] No If yes, describe impact and migration instructions. ## Related issues Link related issues and discussions. Example: Closes #123 ## Security considerations Note any security implications (auth, secrets, PII, sandboxing, etc.). ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…maximhq#5145) ## Summary Briefly explain the purpose of this PR and the problem it solves. ## Changes - What was changed and why - Any notable design decisions or trade-offs ## Type of change - [ ] Bug fix - [ ] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Describe the steps to validate this change. Include commands and expected outcomes. ```sh # Core/Transports go version go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` If adding new configs or environment variables, document them here. ## Screenshots/Recordings If UI changes, add before/after screenshots or short clips. ## Breaking changes - [ ] Yes - [ ] No If yes, describe impact and migration instructions. ## Related issues Link related issues and discussions. Example: Closes maximhq#123 ## Security considerations Note any security implications (auth, secrets, PII, sandboxing, etc.). ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…maximhq#5145) ## Summary Briefly explain the purpose of this PR and the problem it solves. ## Changes - What was changed and why - Any notable design decisions or trade-offs ## Type of change - [ ] Bug fix - [ ] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [ ] Core (Go) - [ ] Transports (HTTP) - [ ] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Describe the steps to validate this change. Include commands and expected outcomes. ```sh # Core/Transports go version go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` If adding new configs or environment variables, document them here. ## Screenshots/Recordings If UI changes, add before/after screenshots or short clips. ## Breaking changes - [ ] Yes - [ ] No If yes, describe impact and migration instructions. ## Related issues Link related issues and discussions. Example: Closes maximhq#123 ## Security considerations Note any security implications (auth, secrets, PII, sandboxing, etc.). ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [ ] I added/updated tests where appropriate - [ ] I updated documentation where needed - [ ] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable

Summary
Fixes a bug in
SecretVar.UnmarshalJSONwhere JSON objects that do not contain a"value"field (e.g.,{"env_var":"MY_KEY","from_env":true}) were not being parsed correctly as the structured compat format. The previous logic usedsonic.Getto check for a"value"key, which caused the object to fall through to plain-string handling instead of the struct deserialization path.Changes
sonic.Get(data, "value")existence check with a direct byte-level inspection (bytes.TrimSpace) to detect whether the input is a JSON object ({). This ensures any JSON object — with or without a"value"field — is routed through thesecretVarCompatstruct unmarshaling path.from_envformat without a"value"field to prevent regression.Type of change
Affected areas
How to test
go test ./core/schemas/... -run TestSecretVar_UnmarshalJSON_BackwardCompatExpected: all subtests pass, including the new
from_env without value fieldcase which verifies thatenv_var/from_envobjects without a"value"key correctly resolve the environment variable and set the ref toenv.MY_KEY.Screenshots/Recordings
N/A
Breaking changes
Related issues
N/A
Security considerations
This change affects how secret variable references are resolved from environment variables. The fix ensures env-backed secrets are correctly identified and resolved rather than silently falling back to treating the raw JSON as a plain string value, which could have led to secrets being mishandled or unresolved.
Checklist
docs/contributing/README.mdand followed the guidelines