Skip to content

v4.0.0 planned for November 4: please test rc.7 #469

Open

Description

@ingydotnet

Update 4.0.0-rc.9 is latest

I have tentative plans to release
go-yaml v4.0.0 on Wednesday, November 4, 2026.

Before then, I would appreciate help testing the newly published
v4.0.0-rc.7 against projects that already use a v4 release candidate.
November 4 is the planned date; reported problems will inform release
readiness.

Testing rc.7

From your project's Go module directory:

go get go.yaml.in/yaml/v4@v4.0.0-rc.7

Please run your normal tests and relevant YAML parsing and serialization
checks.
Pay particular attention to custom marshalers and unmarshalers, formatting,
error handling, and existing regression cases.
If your module has a replace directive for go-yaml, ensure it actually
selects rc.7 for this test.
For a module replacement, go list -m -json go.yaml.in/yaml/v4 shows the
required version and any replacement.

Report results here

Please report problems in comments on this issue, so we can track them
together before the release.

Include:

  • Your project and the revision tested.
  • Your Go version and confirmation that the test used rc.7.
  • The failing command, output, and expected behavior.
  • A small reproducer or a link to an existing report, if possible.

A comment confirming successful testing is also helpful.
Please describe which tests you ran; a successful test run is evidence for
that workload rather than a guarantee of complete compatibility.

Results by Tuesday, November 3, 2026 would be appreciated, but later
reports are welcome.

Downstream outreach

These 22 projects were selected because they directly depend on a go-yaml
v4 release candidate and each has over 1,000 GitHub stars.
Notification links will be added as the notices are filed.
Test results will be updated manually from comments on this issue.
No response means testing has not been confirmed.

Project Notification Test result
Gardener Issue #16181 √
Actionlint Issue #765 √
Terramate Issue #2397 Awaiting results
Dasel Issue #568 √ TomWright/dasel#569 fix submitted
Cog Issue #3212 Awaiting results
Updatecli Issue #11150 √
Gitea Issue #40145 √
Docker Compose Issue #14432 √
AdGuard Home Issue #8683 Closed by downstream
Authelia Issue #13659 √
Grafana Loki Issue #26037 Awaiting results
yq Issue #2955 √ mikefarah/yq#2956 fix submitted
Talos Issue #14805 √
OSV-Scanner Issue #3195 √
Atlantis Issue #7038 √ runatlantis/atlantis#7042 fixes issues
ko Issue #1781 √ ko-build/ko#1781 (comment)
evcc Issue #35660 √ afaict
Incus Issue #4309 √ afaict
Apache Dubbo-go Issue #3785 √ afaict
DDEV Issue #9034 √ ddev/ddev#9035
Apptainer Issue #3897 √
doco-cd Issue #2131 √

Thanks for helping test the release!

-- Ingy döt Net

Activity

  1. self-assigned this
    on Oct 31, 2026
  2. Crowley723 commented on Oct 31, 2026

    @Crowley723

    Project: https://github.com/authelia/authelia
    PR: authelia/authelia#13660
    Test Run: https://buildkite.com/authelia/authelia/builds/60768/canvas

    5 failing unit tests, related to changed error codes and does not affect the application at all (all integration/e2e testing passes).

    Errors:

    Error message not equal:
    	expected: "could not parse the YAML database: go-yaml load error in scanner (while scanning for the next token) at L2.C1: found character that cannot start any token"
    	actual  : "could not parse the YAML database: yaml: line 2: found character that cannot start any token"
    
    Error:      	Error "could not parse the YAML database: yaml: line 2: found character that cannot start any token" does not contain "could not parse the YAML database: go-yaml load error in scanner (while scanning for the next token) at L2.C1: found character that cannot start any token"
    
    Error message not equal:
      	expected: "error reading the authentication database: could not parse the YAML database: go-yaml load error in scanner at L4.C6: mapping values are not allowed in this context"
      	actual  : "error reading the authentication database: could not parse the YAML database: yaml: line 4: mapping values are not allowed in this context"
    
    Error message not equal:
      	expected: "go-yaml load error in parser (while parsing a flow node) at L2.C1: did not find expected node content"
      	actual  : "yaml: line 2: did not find expected node content"
    
    Error message not equal:
      	expected: "go-yaml load error in parser (while parsing a flow node) at L2.C1: did not find expected node content"
      	actual  : "yaml: line 2: did not find expected node content"
    
  3. james-d-elliott commented on Oct 31, 2026

    @james-d-elliott

    Nice work.

    The changes to comment parsing are the ones that are most likely to catch users out I think.

    Input rc.6 rc.7
    password: "abc"#comment Loads, password is abc found a comment without preceding whitespace
    groups: [a, b]#x Loads, groups are [a, b] found a comment without preceding whitespace
    a: |#c (block scalar header) Loads, a is x found a comment without preceding whitespace
  4. ingydotnet commented on Nov 1, 2026

    @ingydotnet
    MemberAuthor

    @james-d-elliott

    6. Nice work.
    The changes to comment parsing are the ones that are most likely to catch users out I think.

    These aren't changes to comment handling. They are fixes to disallow invalid YAML.
    No changes to comment handling were planned for v4.
    We decided to leave v3 comment processing alone and make all the changes we want in the Comment-Model plugin API. (forthcoming).

    `password: "abc"#comment`
    Loads, password is `abc`
    `found a comment without preceding whitespace`
    

    https://play.yaml.com/?show=gdhflLnJPpxHUrsS#cGFzc3dvcmQ6ICJhYmMiI2NvbW1lbnQ=

    `groups: [a, b]#x`
    Loads, groups are `[a, b]`
    `found a comment without preceding whitespace`
    

    https://play.yaml.com/?show=gdhflLnJPpxHUrsS#Z3JvdXBzOiBbYSwgYl0jeA==

    `a: |#c` (block scalar header)
    Loads, `a` is `x`
    `found a comment without preceding whitespace`
    

    https://play.yaml.com/?show=gdhflLnJPpxHUrsS#YTogfCNj

    We're not protecting spec invalid YAML. (although we could via a plugin if it was prevalent enough)

  5. james-d-elliott commented on Nov 1, 2026

    @james-d-elliott

    You sir mistake me haha (I think?). I agree with the change, and the invalid YAML being unsupported and this is entirely defensible, just noting that it's the likely thing that will cause the most issues (in my opinion of course) so that everyone else who looks here can be aware and can prepare themselves and possibly their users. I did note the responsible commits also restored disabled checks.

  6. silverwind commented on Nov 1, 2026

    @silverwind
    Contributor

    Tested rc.7 with go1.27.3 in three Gitea projects. Build and vet pass in all three. Two behavior changes show up in tests:

    1. https://github.com/go-gitea/gitea at da7b81d4079dca56ee7e9485f2ae287fafc249ab (previously on v4.0.0-rc.6.0.20261013184558-04dd63131525): one golden-file test fails because the key on is now emitted as "on": instead of 'on':. Equivalent YAML, we'll update the fixture. Everything else passes.

    2. https://gitea.com/gitea/runner at a46d3f3edac73acc1ad0e5c02fd005f88d5d3bf4 (same pseudo-version): two tests fail because the document : is now accepted. The tests used it as invalid input.

      var node yaml.Node
      err := yaml.NewDecoder(strings.NewReader(":")).Decode(&node)
      // rc.6 pseudo-version: (while parsing a block mapping) at L1.C1: did not find expected key
      // rc.7:                err=<nil>, MappingNode with one empty key/value pair

      yaml.Unmarshal([]byte(":"), &v) behaves the same way. We assume this is the intended empty-key fix and will adjust our tests. Could you confirm?

      @silverwind confirmed. : is valid YAML. https://play.yaml.com/?show=gdhflLnJPpxHUrsS#Og== - @ingydotnet

    3. https://gitea.com/gitea/actionslib at de5ccd9d3196420f9ef5044598ad40dde8d66664 (previously on v4.0.0-rc.6): all tests pass.

    Written by Claude (Opus 5.5).

  7. SilentNul commented on Nov 1, 2026

    @SilentNul

    Hi @ingydotnet — thanks for the rc.7 heads-up in apache/dubbo-go#3785. We
    tested go.yaml.in/yaml/v4@v4.0.0-rc.7 there and hit one compile-time
    regression
    that blocks part of our tree. Reporting it here before the Nov 4
    tag, as requested.

    Reproducer

    A module that only uses the public API, no dubbo-go involved:

    package main
    
    import (
    	"bytes"
    
    	"go.yaml.in/yaml/v4"
    )
    
    func main() {
    	var buf bytes.Buffer
    	d, err := yaml.NewDumper(&buf, yaml.WithV3Defaults())
    	if err != nil {
    		panic(err)
    	}
    	d.SetIndent(2) // rc.6: compiles; rc.7: d.SetIndent undefined
    	_ = d.Close()
    }
    $ go get go.yaml.in/yaml/v4@v4.0.0-rc.7
    $ go build .
    main.go:15:4: d.SetIndent undefined (type *yaml.Dumper has no field or method SetIndent)
    

    The same file compiles cleanly if you pin rc.6 instead
    (go get go.yaml.in/yaml/v4@v4.0.0-rc.6 && go build . → exit 0, no output),
    so it is the rc.7 change and nothing else.

    Confirmed the version actually in use:

    $ go list -m -json go.yaml.in/yaml/v4 | grep -E '"Path"|"Version"'
            "Path": "go.yaml.in/yaml/v4",
            "Version": "v4.0.0-rc.7",
    

    What changed

    In rc.6, yaml.Dumper was an exported type alias (yaml.go:555):

    type Dumper = libyaml.Dumper

    so it inherited every method of the internal type, including SetIndent and
    SetCompactSeqIndent.

    In rc.7 it became a wrapper struct that forwards only two methods
    (yaml.go:855-884):

    type Dumper struct {
    	dumper *libyaml.Dumper
    }
    func (d *Dumper) Dump(in any) error
    func (d *Dumper) Close() error

    The internal methods were renamed to SetLegacyEncoderIndent /
    SetLegacyEncoderCompactSeqIndent; the wrapper does not expose either.

    Impact

    github.com/pb33f/libopenapi v0.38.7 (widely used for OpenAPI
    parsing/rendering) does exactly this in (*Document).RenderWithIndention
    (datamodel/high/v3/document.go:175-182):

    libopenapi@v0.38.7/datamodel/high/v3/document.go:178:13:
        yamlDumper.SetIndent undefined (type *yaml.Dumper has no field or method SetIndent)
    

    Bisected locally: the depending module builds cleanly on rc.6 and fails on
    rc.7 — it is purely the Dumper change, not a libopenapi upgrade. This breaks
    tools/protoc-gen-triple-openapi in apache/dubbo-go (a separate module from the
    main one).

    Suggestion

    Any of these keeps v4.0.0 source-compatible:

    1. Re-add SetIndent / SetCompactSeqIndent as forwarding methods on the
      Dumper wrapper, deprecated and removed in v5, or
    2. Keep type Dumper = libyaml.Dumper for this release and introduce the
      wrapper in a later minor, or
    3. If the removal is intended, flag it as a breaking change in the release
      notes — Encoder.SetIndent is the replacement, but NewDumper users have
      no drop-in path today.

    What still works

    The main dubbo-go module builds and its YAML-consuming packages pass on rc.7
    (details in apache/dubbo-go#3785); only that OpenAPI codegen tool submodule is
    blocked. Happy to re-test as soon as a follow-up rc lands.

    Environment
    • go.yaml.in/yaml/v4 v4.0.0-rc.6 → v4.0.0-rc.7
    • Go 1.25.12, windows/amd64
    • apache/dubbo-go main @ 555a9ba
    • github.com/pb33f/libopenapi v0.38.7
  8. ccoVeille commented on Nov 1, 2026

    @ccoVeille
    Contributor

    hi @SilentNul

    This one is on me. I made the change here

    I noticed that Dumper was exposing way to much method inherited from v3 Encoder.

    SetIndent was providing no way to report the i valid number of indentation (<= 0 and >9). It was either silent or panicking. Not a sane design for a brand new API.

    So I wiped down the methods on Dumper (and Loader). It's a choice we did on purpose. This should have never reached an -rc, but we preferred to remove it as if it was an -alpha.

    There is a solution anyway.

    You can use yaml.WithIdent

    package main
    
    import (
    	"bytes"
    
    	"go.yaml.in/yaml/v4"
    )
    
    func main() {
    	var buf bytes.Buffer
    	d, err := yaml.NewDumper(&buf, yaml.WithV3Defaults(), yaml.WithIdent(2))
    	if err != nil {
    		panic(err)
    	}
    	_ = d.Close()
    }

    WithIdent is the solution for passing the number of ident with the v4

  9. SilentNul commented on Nov 1, 2026

    @SilentNul

    Thanks, @ccoVeille! Confirmed on rc.7 — the option path works as expected:

    NewDumper(&buf, yaml.WithV3Defaults(), yaml.WithIndent(2)) produces the expected 2-space indentation. Both WithIndent(0) and WithIndent(99) return yaml: indent must be between 2 and 9 spaces — unlike the direct Dumper.SetIndent path, which silently ignored out-of-range values (verified on rc.6: SetIndent(0) and SetIndent(99) both still emitted 2-space output, no error).

    One note for downstream users: WithIndent exists in rc.6 as well and carries the same range check, so libraries currently calling Dumper.SetIndent can switch to the option and stay compatible with both rc.6 and rc.7, without version-specific code.

    On our side the main module builds and its YAML-consuming packages pass on rc.7 (apache/dubbo-go#3785, bump in #3786); only one codegen submodule stays on rc.6 until pb33f/libopenapi adopts the option.

    Thanks for the quick response!

  10. kimdre commented on Nov 1, 2026

    @kimdre

    Hi, I'm the maintainer of doco-cd. I did not encounter any issues/regressions in my tests with v4.0.0-rc.7.

    Request: kimdre/doco-cd#2131

    All my tests passed:

    Thanks for the heads-up and for the release candidates!

  11. gibmat commented on Nov 1, 2026

    @gibmat

    Chiming in from the Debian side, currently there are eleven packages in unstable that have a dependency on go.yaml.in/yaml/v4.

    Seven build fine with rc.7:

    • distrobuilder
    • golang-github-futurfusion-openfga-sync
    • golang-github-pb33f-jsonpath
    • golang-github-pb33f-ordered-map-v2
    • golang-gopkg-dnaeon-go-vcr.v4
    • incus
    • oras

    Four don't build with rc.7:

    • dasel
    • golang-github-pb33f-libopenapi
    • golang-github-pb33f-libopenapi-validator
    • yq-go

    dasel and yq are mentioned above in the "downstream outreach" list, and I've commented on those two specific issues.

    PR fixess submitted to yq and dasel. thanks. -- @ingydotnet

  12. ingydotnet commented on Nov 1, 2026

    @ingydotnet
    MemberAuthor

    @gibmat @SilentNul https://github.com/pb33f/libopenapi/blob/main/go.mod#L7 has forked this project.

    Note: We see merit in @pb33f's changes and will likely adopt them, but nothing was reported by them here.

  13. ccoVeille commented on Nov 1, 2026

    @ccoVeille
    Contributor

    @gibmat

    Can you share the URL of the CI that fails for this?

    golang-github-pb33f-libopenapi
    golang-github-pb33f-libopenapi-validator

    Because I don't understand what could fail if they are using a fork of our code, that wasn't updated for weeks.

    Some pointers would help us.

  14. jamengual commented on Nov 1, 2026

    @jamengual

    Tested v4.0.0-rc.7 in runatlantis/atlantis (runatlantis/atlantis#7042), revision c9f261f, Go 1.27.3 on darwin/amd64 plus Linux CI. Full suite passes.

    Behavior changes we saw, none of them blockers:

    1. A bare ":" now decodes to {null: null}; rc.6 returned did not find expected key. That's correct under YAML 1.2 (an implicit block mapping entry may have an empty key). Three of our tests used : as their "invalid YAML" input, and we switched them to a: b: c.
    2. Decoding "? [foo]\n: bar\n<<: {}\n" into any now returns cannot use '[]interface {}{"foo"}' as a map key; try decoding into yaml.Node instead of the recovered panic text hash of unhashable type. Nicer.
    3. Small inconsistency: parser errors use two formats, yaml: line 1: mapping values are not allowed in this context and go-yaml load error in constructor at L1.C3: .... Is that intended for v4.0.0?

    Thanks for the heads-up!

  15. rfay commented on Nov 1, 2026

    @rfay

    passed all tests on all platforms.

  16. changed the title [-]v4.0.0 planned for November 4: please test rc.7[/-] [+]v4.0.0 planned for November 4: please test rc.8[/+] on Nov 2, 2026
  17. changed the title [-]v4.0.0 planned for November 4: please test rc.8[/-] [+]v4.0.0 planned for November 4: please test rc.7[/+] on Nov 2, 2026
  18. ndeloof commented on Nov 2, 2026

    @ndeloof

    Report: Node.Decode no longer applies the default alias/depth limits (v4.0.0-rc.5 → rc.8)

    While testing rc.8 in compose-go (compose-spec/compose-go#981), our loader tests stopped returning: a document of deeply nested aliases (TestAliasBombPrevented) is now expanded without limit instead of being rejected with "excessive aliasing". It passes with rc.4 and hangs with rc.6, rc.7 and rc.8.

    The cause, as far as we can tell, is that Node.Decode builds its constructor from DefaultOptions, which has no AliasCheck/DepthCheck, while Node.Load (through ApplyOptions), Unmarshal and the decoder apply them. Our UnmarshalYAML implementation expands the aliases by decoding a node, so it lost the limits.

    Our workaround is to call Node.Load instead, one line in loader/reset.go L80-L84.

    Is this change of behavior known and intended for Node.Decode? If it is, we will keep the workaround. If not, other callers decoding nodes from UnmarshalYAML are likely exposed too.

    @ndeloof see #475

    @ndeloof please try v4.0.0-rc.9 and report back.

  19. Ly-Joey commented on Nov 2, 2026

    @Ly-Joey

    Hello from osv-scanner!
    Our tests at google/osv-scanner#3198 pass with no issues :D

  20. imharjot commented on Nov 3, 2026

    @imharjot

    I tested v4.0.0-rc.9 against the yq compatibility branch in mikefarah/yq#2956 at d84b917c9146874b6ca1933300382add1f44aee4, using Go 1.26.4 on macOS arm64. I ran the same revision with rc.7 as a control. The only dependency change was go get go.yaml.in/yaml/v4@v4.0.0-rc.9, and go list -m go.yaml.in/yaml/v4 confirmed each selected version.

    Both builds passed, and bash scripts/acceptance.sh passed all 173 CLI checks on each version. I also reran the YAML parse and format, anchor and alias, cross-document alias cycle, and decoder anchor-reset tests with -race. Those passed on both versions.

    go test -race -count=1 -json ./... had the same result on each version: 521 tests passed and TestJSONScenarios failed. Its bad json case expected json: string of object unexpected end of JSON input and got invalid character 'b' after object key:value pair on both rc.7 and rc.9. I didn't see a new failure from upgrading to rc.9 in this workload.

  21. gibmat commented on Nov 3, 2026

    @gibmat

    Can you share the URL of the CI that fails for this?
    golang-github-pb33f-libopenapi
    golang-github-pb33f-libopenapi-validator
    Because I don't understand what could fail if they are using a fork of our code, that wasn't updated for weeks.
    Some pointers would help us.

    @ccoVeille I performed a local rebuild of those Debian packages with an updated go-yaml v4, so no public CI links to point to, sorry.

    Both packages are a bit out of date, so maybe current versions build properly. :)

    https://tracker.debian.org/pkg/golang-github-pb33f-libopenapi
    https://tracker.debian.org/pkg/golang-github-pb33f-libopenapi-validator

  22. acumino commented on Nov 3, 2026

    @acumino

    Hi, @ingydotnet

    I ran the Gardener test with v4.0.0-rc.7. All tests passed with no issues 😄.

  23. ndeloof commented on Nov 3, 2026

    @ndeloof

    Tested v4.0.0-rc.9 downstream, and it looks good.

    • compose-go (compose-spec/compose-go#987): bump only, no workaround needed anymore. The full CI is green (Go 1.26 and 1.27 on Linux, macOS and Windows), including our alias-bomb test that never returned with rc.8.
    • docker/compose (docker/compose#14446): bump only, unit and e2e suites are green (plugin and standalone modes, lint, validations).

    Thanks for the quick fix in #475: the Node.Decode default limits are back and nothing else regressed on our side.

  24. ccoVeille commented on Nov 3, 2026

    @ccoVeille
    Contributor

    Can you share the URL of the CI that fails for this?
    golang-github-pb33f-libopenapi
    golang-github-pb33f-libopenapi-validator
    Because I don't understand what could fail if they are using a fork of our code, that wasn't updated for weeks.
    Some pointers would help us.

    @ccoVeille I performed a local rebuild of those Debian packages with an updated go-yaml v4, so no public CI links to point to, sorry.

    Both packages are a bit out of date, so maybe current versions build properly. :)

    https://tracker.debian.org/pkg/golang-github-pb33f-libopenapi
    https://tracker.debian.org/pkg/golang-github-pb33f-libopenapi-validator

    @gibmat

    We know pb33f forked our lib, and no recents commit we made landed on that fork.

    We have a ticket to include the commit pb33f made on their fork

    maybe they will switch back to our lib at some point.

    But all these are out of our control.

    So for now, I'll say we are good.

  25. Shanmukh-l33t commented on Nov 9, 2026

    @Shanmukh-l33t

    Report for rhysd/actionlint as requested in the release notice — tested against the final v4.0.0: PASS, no blocking problems.

    • Project revision: rhysd/actionlint@011a6d1 (main), migration branch https://github.com/Shanmukh-l33t/actionlint/tree/bump-go-yaml-v4.0.0, commit def8b7e87188481eedd1dc5cd9ce8258fa765c3b
    • Go version: go1.27.3, linux/amd64 (ShellCheck 0.9.0 on PATH)
    • Commands: go get go.yaml.in/yaml/v4@v4.0.0 && go mod tidy && go build ./... && go vet ./... && go test -p 2 ./...
    • Result: full suite green except two scripts/ packages that already fail on pristine main in my environment (a golden playground-URL encoding and a network-dependent test) — identical failure set before and after the bump, so unrelated to v4.0.0.

    API changes I had to migrate (from v4.0.0-rc.3):

    • *yaml.ParserError no longer exists; *yaml.TypeError remains only as a deprecated alias whose Errors field is now []string, and yaml.Unmarshal never returns it — the decoder reports *yaml.LoadErrors (multiple *LoadError with Message + Mark) or a bare *LoadError for single syntax errors.
    • Message/position differences vs rc.3, all verified against golden files:
      • syntax-error columns are now 1-based (2:7 → 2:8);
      • unknown-anchor errors now carry the reference position instead of 0:0 and drop the yaml: prefix;
      • multi-error text is a single line, yaml: construct errors: line 4: …; line 5: …, instead of newline-joined yaml: unmarshal errors:;
      • type errors read cannot construct !!int … instead of cannot unmarshal !!int ….

    No failures, so no reproducer needed. Follow-up tracked in rhysd/actionlint#765 (my full test report) and the rc.6 migration rhysd/actionlint#735.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions