Skip to content

fix(gen): omit unset flattened-oneOf struct fields from requests - #88

Merged
ysyneu merged 1 commit into
mainfrom
fix/gen-flattened-oneof-struct-fields
Oct 8, 2026
Merged

ysyneu merged 1 commit into
mainfrom
fix/gen-flattened-oneof-struct-fields

Conversation

@UlricQin

@UlricQin UlricQin commented Oct 8, 2026

Copy link
Copy Markdown
Member

Problem

DashboardVariable is one flattened struct covering the datasource, custom and query arms. Only the query arm carries variable_query, but the generated tag was:

VariableQuery DashboardVariableQuery `json:"variable_query,omitempty"`

,omitempty never drops a struct value, so every datasource or custom variable was sent as:

{"kind": "datasource", "name": "metrics_ds", "variable_query": {"kind": ""}}

The API validates each arm strictly, so it rejected /monit/dashboard/create, /monit/dashboard/update and /monit/dashboard/panel/preview with unknown field "variable_query". That covers any dashboard that has a datasource or custom variable.

Cause

isStructSchema resolves a $ref by looking at the raw target schema. For DashboardVariableQuery that schema is a oneOf, so the function returned false. emitModels, however, emits a named oneOf of object arms as one flattened struct (resolveObject → mergeAllOf). Because the field was misclassified, it skipped the existing ,omitzero rule for optional struct-typed request fields.

Fix

Classify the $ref target the same way emitModels emits it: run it through resolveObject first. Inline oneOf schemas still return false; goTypeOf emits those as any.

Regenerating changes exactly one line in models_gen.go: the variable_query tag goes from omitempty to omitzero. No types change and nothing becomes a pointer, so this is not a breaking change.

Tests

  • TestEmitStructOptionalFlattenedOneOfRequestFieldOmitsZero (generator): an optional request field whose $ref target is a oneOf of objects is emitted with ,omitzero.
  • TestDashboardVariableOmitsUnsetVariableQuery (SDK): a datasource variable marshals without variable_query, and a query variable still includes it.

Both tests fail on main and pass with this change. go generate ./... reproduces the committed output, golangci-lint run reports 0 issues, and go test ./... passes.

I also built the CLI against this branch and ran it end to end against a test account, using a dashboard with a datasource variable. Panel preview, create, get and delete all succeeded, and the stored variable has no variable_query key.

isStructSchema classified a $ref to a oneOf of object arms by its raw
schema and returned false, but emitModels emits such a schema as one
flattened struct. An optional request field of that type therefore got
`,omitempty`, which never drops a struct value, so an unset field was
sent as an object holding only an empty discriminator.

DashboardVariable.VariableQuery was affected: every datasource or custom
variable went out with "variable_query":{"kind":""}, and the API rejected
dashboard create, update and panel preview with
`unknown field "variable_query"`.

Classify the resolved (flattened) schema instead, which gives the field
`,omitzero`. Regenerating changes only that one tag.
@ysyneu
ysyneu merged commit 290561f into main Oct 8, 2026
4 checks passed
@ysyneu
ysyneu deleted the fix/gen-flattened-oneof-struct-fields branch October 8, 2026 08:57
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