Skip to content

fix(openapi)!: remove name from ConfigUser request schema#157

Open
Dav-14 wants to merge 1 commit into
mainfrom
fix/configuser-name-contract
Open

fix(openapi)!: remove name from ConfigUser request schema#157
Dav-14 wants to merge 1 commit into
mainfrom
fix/configuser-name-contract

Conversation

@Dav-14
Copy link
Copy Markdown
Contributor

@Dav-14 Dav-14 commented Jun 4, 2026

Summary

  • The published openapi.yaml advertises an optional name property on ConfigUser (used by POST /configs and PUT /configs/{id}), but the server-side Go struct webhooks.ConfigUser (pkg/config.go) only declares Endpoint, Secret, EventTypes. Server-side decoding runs with json.Decoder.DisallowUnknownFields() (pkg/server/helpers.go:18), so any client honouring the spec and sending name is rejected with 400 VALIDATION — Request body contains unknown field "name" and no config is created.
  • Formance's terraform-hcp-proxy hits this in production whenever a manifest declares a webhooks config: the manifest's natural key was being marshalled into name, dispatch failed, deployment went errored.
  • This PR aligns the spec with the implementation: drop name from ConfigUser. The Config response schema (WebhooksConfig) was not exposing name either, so response shape is unchanged.

History — has name ever worked?

No. name first appeared in openapi.yaml in commit a16b8397 (Jan 17, 2024) — feat(webhooks): ENG-459 give optional names to webhook configs (#1123). That same commit:

  • ✅ added a name column via cmd/migrate.go (still in the schema today)
  • ✅ added Name string \json:"name" bun:"name,nullzero"`to the response/storage structConfig`
  • ✅ added name: to the request schema ConfigUser in openapi.yaml
  • ❌ did NOT add Name to the request Go struct ConfigUser
  • ❌ did NOT add any code path that writes cfg.Name = …

git grep across v2.3.2 confirms no code anywhere outside the generated SDK references .Name on a ConfigUser. Net effect since Jan 2024:

Operation Behaviour
Creation (insertConfig) name rejected by DisallowUnknownFields() — has never worked
Storage (DB column) column exists, default empty, no path populates it — dead column for ~2 years
Get / list (raw HTTP) Config Go struct marshals "name":"" because of the json tag — raw clients see an empty string
Get / list (SDK) response schema WebhooksConfig does not expose name — SDK consumers never see it either

So this PR removes a spec promise that the implementation has never made good on. SDK consumers using ConfigUser.Name were getting silent 400s in production.

Why this PR is large

Most of the diff is Speakeasy SDK regen against a slightly older baseline (gen.lock was several feature versions behind). Reviewer focus should be on openapi.yaml (4 deleted lines); the rest is mechanical Speakeasy output. Happy to split the SDK regen out if preferred, but they need to land together to keep the SDK consistent with the spec.

BREAKING CHANGE

pkg/client/models/components.ConfigUser loses Name *string and GetName(). Call sites must drop the field. The field was non-functional at runtime, so removal has no behavioural impact — only a compile-time SDK shape change.

Follow-ups (out of scope)

  • The DB has an empty, unused name column. Drop it in a follow-up migration if appropriate.
  • If we want nameable configs, that's a separate feat: PR — needs Name on the request struct, a handler change, and the response schema to expose it.

Test plan

  • just generate-client — Speakeasy regen succeeded; new ConfigUser has only Endpoint, Secret, EventTypes.
  • go build ./... — clean.
  • go test ./pkg/... — all pass (pkg, pkg/backoff, pkg/storage/postgres, pkg/worker).
  • CI to run the integration suite (-tags it) end-to-end.

The published openapi.yaml declared an optional `name` property on
`ConfigUser` (the insertConfig / updateConfig request body). The
server-side Go struct never had a `Name` field — only the response
type `Config` does — and `decodeJSONBody` runs with
`json.Decoder.DisallowUnknownFields()` (pkg/server/helpers.go).

Net effect: any client honouring the spec and sending `name` got
back `400 VALIDATION — Request body contains unknown field "name"`
without the config being created. Formance's terraform-hcp-proxy
hits this in production whenever a manifest declares a webhooks
config (the manifest's natural key was being marshalled into
`name`).

This commit aligns the spec with what the server actually accepts:
drop `name` from `ConfigUser`. The `Config` response schema was
not exposing `name` either, so the response shape is unchanged.

SDK impact: the Speakeasy-generated `pkg/client` is regenerated.
`ConfigUser.Name` and `ConfigUser.GetName()` are gone. Anyone
relying on them was already getting silent 400s at runtime, so
the surface change is the only thing that changes.

BREAKING CHANGE: ConfigUser.Name and the corresponding accessor
are removed from the Go SDK. Existing call sites must drop the
field.
@Dav-14 Dav-14 requested a review from a team as a code owner June 4, 2026 20:58
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (56)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum, !**/*.sum
  • openapi.yaml is excluded by !**/*.yaml
  • pkg/client/.gitignore is excluded by !pkg/client/**
  • pkg/client/.speakeasy/gen.lock is excluded by !**/*.lock, !**/*.lock, !pkg/client/**
  • pkg/client/.speakeasy/gen.yaml is excluded by !**/*.yaml, !pkg/client/**
  • pkg/client/README.md is excluded by !pkg/client/**
  • pkg/client/USAGE.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/configuser.md is excluded by !pkg/client/**
  • pkg/client/docs/models/components/security.md is excluded by !pkg/client/**
  • pkg/client/docs/models/sdkerrors/errorresponse.md is excluded by !pkg/client/**
  • pkg/client/docs/sdks/formance/README.md is excluded by !pkg/client/**
  • pkg/client/docs/sdks/v1/README.md is excluded by !pkg/client/**
  • pkg/client/formance.go is excluded by !pkg/client/**
  • pkg/client/go.mod is excluded by !**/*.mod, !pkg/client/**
  • pkg/client/internal/config/sdkconfiguration.go is excluded by !pkg/client/**
  • pkg/client/internal/hooks/clientcredentials.go is excluded by !pkg/client/**
  • pkg/client/internal/hooks/hooks.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/env.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/form.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/headers.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/json.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/oauth2_credentials.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/oauth2_sessions.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/pathparams.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/queryparams.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/requestbody.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/retries.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/security.go is excluded by !pkg/client/**
  • pkg/client/internal/utils/utils.go is excluded by !pkg/client/**
  • pkg/client/models/components/attempt.go is excluded by !pkg/client/**
  • pkg/client/models/components/attemptresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/configchangesecret.go is excluded by !pkg/client/**
  • pkg/client/models/components/configresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/configsresponse.go is excluded by !pkg/client/**
  • pkg/client/models/components/configuser.go is excluded by !pkg/client/**
  • pkg/client/models/components/httpmetadata.go is excluded by !pkg/client/**
  • pkg/client/models/components/security.go is excluded by !pkg/client/**
  • pkg/client/models/components/webhooksconfig.go is excluded by !pkg/client/**
  • pkg/client/models/operations/activateconfig.go is excluded by !pkg/client/**
  • pkg/client/models/operations/changeconfigsecret.go is excluded by !pkg/client/**
  • pkg/client/models/operations/deactivateconfig.go is excluded by !pkg/client/**
  • pkg/client/models/operations/deleteconfig.go is excluded by !pkg/client/**
  • pkg/client/models/operations/getmanyconfigs.go is excluded by !pkg/client/**
  • pkg/client/models/operations/insertconfig.go is excluded by !pkg/client/**
  • pkg/client/models/operations/options.go is excluded by !pkg/client/**
  • pkg/client/models/operations/testconfig.go is excluded by !pkg/client/**
  • pkg/client/models/operations/updateconfig.go is excluded by !pkg/client/**
  • pkg/client/models/sdkerrors/errorresponse.go is excluded by !pkg/client/**
  • pkg/client/optionalnullable/optionalnullable.go is excluded by !pkg/client/**
  • pkg/client/optionalnullable/optionalnullable_test.go is excluded by !pkg/client/**
  • pkg/client/retry/config.go is excluded by !pkg/client/**
  • pkg/client/types/decimal.go is excluded by !pkg/client/**
  • pkg/client/types/pointers.go is excluded by !pkg/client/**
  • pkg/client/v1.go is excluded by !pkg/client/**
  • pkg/client/webhooks.go is excluded by !pkg/client/**

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d84d9689-2fe3-4509-a75f-743e9ed39116

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/configuser-name-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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.

1 participant