Skip to content

Conversation

@bhshkh
Copy link
Contributor

@bhshkh bhshkh commented Jan 13, 2026

Reintroduce #1661 only for Firestore

b/456536006

This PR re-implements the fix for ordered dynamic routing headers (originally in #1661) but scopes it strictly to Firestore clients to avoid regressions in other libraries like Storage.

Problem: The Firestore backend requires x-goog-request-params header values to be in a specific order (e.g., project_id must appear before database_id). The current generator uses a Go map iteration to build this header string, resulting in non-deterministic ordering that causes intermittent InvalidArgument errors in the Firestore Go client. A previous attempt to fix this globally (#1661) caused regressions in the Storage client and was reverted.

Solution:

Introduced an allowlist enableOrderedRoutingHeaders in internal/gengapic/generator.go, currently enabled for google.firestore.v1 and google.firestore.admin.v1.
Modified insertDynamicRequestHeaders in internal/gengapic/gengapic.go:

  • For allowlisted packages (Firestore): The code now iterates over the header rules in the order defined in the proto. It checks the routingHeadersMap for each key, appends the value, and deletes the key to prevent duplicates. This ensures deterministic ordering while preserving the "last value wins" semantics for duplicate keys.

  • For other packages (Storage, etc.): The code falls back to the existing behavior (iterating over the map), ensuring zero changes to the generated code for non-target libraries.

@bhshkh bhshkh requested a review from a team as a code owner January 13, 2026 23:38
@bhshkh bhshkh enabled auto-merge (squash) January 13, 2026 23:39
@bhshkh bhshkh changed the title fix(gengapic): Ensure stable order of dynamic Firestore routing headers fix(gengapic): ordered dynamic header values for Firestore Jan 14, 2026
inputType := &descriptorpb.DescriptorProto{
Name: proto.String("InputType"),
Field: []*descriptorpb.FieldDescriptorProto{
{Name: proto.String("field1"), Type: typePtr(descriptorpb.FieldDescriptorProto_TYPE_STRING)},
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm unsure of this typePtr usage. Can't you use https://pkg.go.dev/google.golang.org/protobuf/types/descriptorpb#FieldDescriptorProto_Type.Enum e.g. descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixing in #1686

@bhshkh bhshkh merged commit d903b0d into googleapis:main Jan 14, 2026
8 checks passed
@bhshkh bhshkh deleted the fix/ordered-header-vals-attempt2 branch January 14, 2026 06:47
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