Skip to content

Honor ForceSendFields for query parameters#1728

Open
renaudhartert-db wants to merge 1 commit into
mainfrom
fix/force-send-query-params
Open

Honor ForceSendFields for query parameters#1728
renaudhartert-db wants to merge 1 commit into
mainfrom
fix/force-send-query-params

Conversation

@renaudhartert-db

@renaudhartert-db renaudhartert-db commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Query parameters listed in ForceSendFields are now sent on the wire even when they hold a zero value, matching the behavior that already exists for JSON request bodies. This fixes cases like the pipelines Delete API, where setting Cascade to false and adding it to ForceSendFields did not actually send cascade=false on the wire.

Why

Query parameters are serialized from the request struct's url tag by the go-querystring library. That tag uses omitempty, so a zero-valued scalar field (for example a false bool, a 0 int, or an empty string) is dropped from the URL. ForceSendFields was designed to opt out of exactly this behavior, but it was only ever wired into the marshal package, which handles JSON bodies. go-querystring has no knowledge of ForceSendFields, so adding a query field to it had no effect.

(Path parameters are not affected: they are tagged url:"-" and substituted directly into the URL path, so they never flow through this serialization.)

A user reported this for the pipelines Delete API: Cascade defaults to true server-side, so a caller who wants to delete a pipeline without cascading must send cascade=false explicitly. Adding Cascade to ForceSendFields looked like the right way to do that (it is how the same situation is handled for JSON bodies), but the parameter was silently dropped and the server applied its default. This affected every query parameter across all services, not just cascade, including fields nested inside request sub-structs.

How is this tested?

Added two table-driven tests in httpclient/request_test.go. TestMakeQueryStringForceSendFields covers the top-level cases: zero values dropped without ForceSendFields, a false bool sent when forced, non-zero values still sent without forcing, multiple forced fields, forcing not overriding an explicitly set value, and unknown forced field names being ignored. TestMakeQueryStringForceSendFieldsNested covers nested sub-structs: a nested struct honoring its own ForceSendFields, non-nil and nil pointers to nested structs, and doubly nested fields. Also verified end-to-end by calling the real pipelines Delete and iam.CheckPolicy APIs through a fake HTTP transport and confirming the forced zero values appear in the request URL. The full httpclient test suite passes.

Query parameters are serialized by go-querystring via the `url` struct
tag, which applies `omitempty` but has no knowledge of ForceSendFields.
As a result a zero-valued scalar field listed in ForceSendFields (for
example a false `cascade` bool on the pipelines Delete request) was
dropped instead of being sent on the wire, even though the same field
would be honored in a JSON body.

Re-add force-sent fields in makeQueryString after go-querystring runs,
mirroring the basic-type-only ForceSendFields semantics already used by
the marshal package for JSON bodies. The walk recurses into nested
structs and non-nil pointers to structs so that each struct level honors
its own ForceSendFields, using the same `parent[child]` key notation
go-querystring emits. Pointer fields are otherwise left untouched (a
non-nil pointer is already serialized and a nil pointer means "not
set"), and values match go-querystring's formatting via fmt.Sprint.

Co-authored-by: Isaac
Signed-off-by: Ubuntu <renaud.hartert@databricks.com>
@renaudhartert-db renaudhartert-db force-pushed the fix/force-send-query-params branch from c59ade0 to 8cf3121 Compare June 19, 2026 15:25
@github-actions

Copy link
Copy Markdown

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/sdk-go

Inputs:

  • PR number: 1728
  • Commit SHA: 8cf312138f3f651287b8453a1b7dd1914a6ecba7

Checks will be approved automatically on success.

@renaudhartert-db renaudhartert-db changed the title Honor ForceSendFields for query and path parameters Honor ForceSendFields for query parameters Jun 19, 2026
@renaudhartert-db renaudhartert-db deployed to test-trigger-is June 19, 2026 15:26 — with GitHub Actions Active
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