fix: enable field removal for destination metadata/delivery_metadata#844
Open
fix: enable field removal for destination metadata/delivery_metadata#844
Conversation
…ion update
Replace MergeStringMaps with direct assignment for metadata and
delivery_metadata, matching existing filter behavior. User-defined
key-value maps need full replacement semantics so keys can be removed
and the map can be cleared with {}.
Config and credentials still use merge since they have structured,
known keys where partial updates make sense.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lWrapper
SDK tests across TS, Go, and Python verifying that filter, metadata,
and delivery_metadata can be set, cleared with {}, have keys removed
via subset, and remain unchanged when omitted.
Also enables nullableOptionalWrapper in Go SDK gen config so the
generated SDK can distinguish "don't send" from "send empty" for
nullable map fields.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
alexbouchardd
approved these changes
Apr 20, 2026
Pagination endpoints return PageIterator<Response> where the body is under .result. Update events.test.ts and tenants.test.ts to use page.result.models instead of response.models. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Destination Field Removal Fix
Problem
Impossible to clear
filter,metadata, ordelivery_metadataon destination update by sending{}.metadata/delivery_metadataused merge semantics — sending{}was a no-opjson:",omitempty"drops empty maps before serialization, so{}never reaches the serverServer Fix
Changed
metadataanddelivery_metadatafrom merge to full replacement (matching howfilteralready worked).null{}{"key": "val"}SDK Status
{}to clear?All 148 TS tests and 11 Python tests pass.
Go SDK Limitation
Go's
omitemptystrips empty maps before serialization —{}becomes indistinguishable from "not sent".Speakeasy has a
nullableOptionalWrapperflag that generates three-stateOptionalNullable[T]types (not set vs null vs value). This would solve it, but the flag is global and all-or-nothing — it wraps ~30+ fields across the entire SDK (Create, Response, Event, Attempt, Tenant), not just the update structs.For example, with the flag enabled, the update struct changes from:
This is what we want — but the same wrapping also applies to every other nullable field:
Tenant.Metadata,Event.Metadata,Attempt.ResponseData,Attempt.Event,DestinationCreateWebhook.Filter, all response structs, etc. (~30+ fields total).DX impact on Go SDK usage
Creating a destination (current):
Creating a destination (with flag):
Clearing metadata on update (with flag):
Reading from response (with flag):
Every nullable field across the SDK requires wrapping/unwrapping — not just the update fields we care about.
What we tried to scope it to update fields only
type: ["object", "null"]) — Speakeasy doesn't distinguish 3.0 vs 3.1, still wraps everythingx-speakeasy-nullableetc.) — doesn't exist in Speakeasy's 52 extensionsNote: Go SDK currently does not support sending
nulleither — only omitted and value. This is a current Outpost limitation, not a design decision. If we want to support explicitnullsemantics in the future, we'd need to explore theOptionalNullablewrapper regardless.Options:
Test plan
destination_handlers_test.go(filter/metadata/delivery_metadata: replaced not merged, cleared with{}, unchanged when omitted)events.test.tsandtenants.test.tsupdated forPageIteratorresponse shape🤖 Generated with Claude Code