Consolidate on go.yaml.in/yaml/v3 - #1719
Merged
Merged
Conversation
protocol pulled in two copies of the same yaml library: gopkg.in/yaml.v3 (auth, configutil, livekit/types) and go.yaml.in/yaml/v3 (transitively via buf.build/go/protoyaml). go.yaml.in is the project's new canonical home, so switch our own imports over and compile it once. RoomConfiguration, RoomEgress and RoomAgent needed care. Their custom UnmarshalYAML took a *yaml.Node, and a yaml decoder only recognizes that method if the Node belongs to its own package. Simply re-pointing the import would mean every caller still decoding with gopkg.in/yaml.v3 -- the server, egress, ingress, sip and cloud all do -- silently stops invoking the custom unmarshaller and falls back to reflective struct decoding of a protobuf message. No compile error; fields such as min_playout_delay just quietly come back zero. Instead these now use the func-based unmarshal signature, which names no types from any yaml package and so is honored by both decoders. Downstream repos keep working unchanged, whichever yaml package they import. Added TestUnmarshallRoomConfigurationBothYAMLPackages, which decodes the same document with both packages and asserts a populated message. Verified it fails (min_playout_delay 0 instead of 42) if the *yaml.Node signature is restored. gopkg.in/yaml.v3 stays in go.mod for that test only; it is no longer in the compiled dependency set. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: a192275 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
paulwe
approved these changes
Aug 16, 2026
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.
Why
protocolcompiles two copies of the same yaml library:gopkg.in/yaml.v3auth/provider.go,utils/configutil/observer.go,livekit/types.gogo.yaml.in/yaml/v3buf.build/go/protoyamlgo.yaml.in/yamlis the project's new canonical home for the same codebase, so this switches our own imports over and leaves one copy in the build.The part that needed care
RoomConfiguration,RoomEgressandRoomAgentimplement a customUnmarshalYAML(value *yaml.Node). That's an interface, and a decoder only recognizes it when theNodeparameter is its own type.Just re-pointing the import would have been a silent, runtime-only break. Every one of these still decodes with
gopkg.in/yaml.v3:…plus
egress,ingress,sipandcloud. Their decoders would stop seeing an Unmarshaler and fall back to reflective struct decoding of a protobuf message — no compile error anywhere,room_configurationsfields such asmin_playout_delayjust quietly come back zero.What this does instead
The three methods now use the older func-based unmarshal signature, which both packages honor because it names no yaml types at all:
So downstream repos keep working unchanged, whichever yaml package they import — no coordinated migration needed.
MarshalYAML() (interface{}, error)was already yaml-package-neutral and is untouched.Verification
TestUnmarshallRoomConfigurationBothYAMLPackagesdecodes the same document with both packages and asserts a fully populated message.*yaml.Nodesignature makes thegopkg.in/yaml.v3subtest fail withexpected: 0x2a, actual: 0x0onmin_playout_delay— precisely the silent-misparse mode above.go test ./...passes.livekit-server'spkg/configagainst this branch and parsed a config containingroom.room_configurationsthroughconfig.NewConfig. All fields (min_playout_delay: 42, nestedegress.room.room_name,agents[]) parse correctly while the server still importsgopkg.in/yaml.v3.server-sdk-go, its compiled dependency set drops to justgo.yaml.in/yaml/v3+protoyaml;gopkg.in/yaml.v3is gone.Note
gopkg.in/yaml.v3stays ingo.mod— the regression test imports it deliberately, since testing the both-decoders property requires both decoders. It is test-only and no longer in the compiled dependency set, so consumers don't build it.🤖 Generated with Claude Code