Repository: twpayne/chezmoi (2026-04-09T23:31:29Z)

Issue:
TOML support was downgraded from v1.1.0 to v1.0.0 in chezmoi 2.70.1
<!--

chezmoi has a strict zero-tolerance policy on LLM contributions. If you use an
LLM (Large Language Model, like ChatGPT, Claude, Gemini, GitHub Copilot, or
Llama) to make any kind of contribution then you will immediately be banned
without recourse.

-->

## Describe the bug

Documents supporting TOML 1.1.0 syntax no longer work.

## To reproduce

Include a toml document targeting toml v1.1.0 in any chezmoidata
The particular file in my own config that causes the most issues is https://github.com/BurnerWah/dotfiles/blob/main/home/dot_config/exact_private_fish/.chezmoidata/subcommand-abbrev-managed.toml (which is something I *really* don't wanna refactor to be compatible with toml 1.0.0 again)

## Expected behavior

TOML 1.1 documents work

## Output of command with the `--verbose` flag

```console
$ chezmoi --verbose status
chezmoi: /Users/burner/.local/share/chezmoi/home/dot_config/exact_private_fish/.chezmoidata/subcommand-abbrev-managed.toml: toml: invalid character at start of key:
```


## Output of `chezmoi doctor`

<details>

```console
$ chezmoi doctor
RESULT    CHECK                       MESSAGE
ok        version                     v2.70.1, commit 420cfdc935590cf62626d347a2a9ec39b2691fc1, built at 2026-04-08T20:52:37Z, built by Homebrew
ok        latest-version              v2.70.1
ok        os-arch                     darwin/arm64
ok        build-info                  -trimpath=true, CGO_ENABLED=1, GOARM64=v8.0
ok        uname                       Darwin macbook.shark-pomano.ts.net 25.4.0 Darwin Kernel Version 25.4.0: Thu Mar 19 19:30:44 PDT 2026; root:xnu-12377.101.15~1/RELEASE_ARM64_T6000 arm64
ok        go-version                  go1.26.2 (gc)
ok        executable                  /opt/homebrew/bin/chezmoi
ok        upgrade-method              brew-upgrade
ok        config-file                 found ~/.config/chezmoi/chezmoi.yaml, last modified 2025-04-29T14:41:12-05:00
ok        source-dir                  ~/.local/share/chezmoi/home is a directory
ok        suspicious-entries          no suspicious entries
warning   working-tree                ~/.local/share/chezmoi is a git working tree (dirty)
ok        dest-dir                    ~ is a directory
ok        hardlink                    created hardlink from ~/.local/share/chezmoi/home to /var/folders/hj/zmd9ty3s16qc3g_xs7kzjz040000gn/T/
ok        symlink                     created symlink from .new-name to .old-name
ok        umask                       022
ok        cd-command                  found /opt/homebrew/bin/fish
ok        cd-args                     /opt/homebrew/bin/fish
ok        diff-command                found /opt/homebrew/bin/delta
ok        edit-command                found /opt/homebrew/bin/code
ok        edit-args                   code --wait
ok        git-command                 found /opt/homebrew/bin/git, version 2.53.0
ok        merge-command               found ~/.local/bin/vimdiff
ok        shell-command               found /opt/homebrew/bin/fish
ok        shell-args                  /opt/homebrew/bin/fish
ok        age-command                 found /opt/homebrew/bin/age, version 1.3.1
ok        gpg-command                 found /opt/homebrew/bin/gpg, version 2.5.18
info      pinentry-command            not set
ok        1password-command           found /opt/homebrew/bin/op, version 2.33.1
info      bitwarden-command           bw not found in $PATH
info      bitwarden-secrets-command   bws not found in $PATH
info      dashlane-command            dcli not found in $PATH
info      doppler-command             doppler not found in $PATH
info      gopass-command              gopass not found in $PATH
info      keepassxc-command           keepassxc-cli not found in $PATH
info      keepassxc-db                not set
info      keeper-command              keeper not found in $PATH
info      lastpass-command            lpass not found in $PATH
info      pass-command                pass not found in $PATH
info      passhole-command            ph not found in $PATH
info      protonpass-command          pass-cli not found in $PATH
info      rbw-command                 rbw not found in $PATH
info      vault-command               vault not found in $PATH
info      secret-command              not set
```

</details>

## Additional context

I assume this is an unintentional regression



Discussion:
This regression is likely due to #4953.



Patch:
diff --git a/go.mod b/go.mod
index 9024866bf9b..7fec4429623 100644
--- a/go.mod
+++ b/go.mod
@@ -55,7 +55,6 @@ require (
 	github.com/muesli/combinator v0.3.0
 	github.com/muesli/termenv v0.16.0
 	github.com/nwaples/rardecode/v2 v2.2.2
-	github.com/pelletier/go-toml/v2 v2.3.0
 	github.com/rogpeppe/go-internal v1.14.1
 	github.com/spf13/cobra v1.10.2
 	github.com/spf13/pflag v1.0.10
@@ -188,6 +187,7 @@ require (
 	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
 	github.com/muesli/reflow v0.3.0 // indirect
+	github.com/pelletier/go-toml/v2 v2.3.0 // indirect
 	github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
 	github.com/pierrec/lz4/v4 v4.1.26 // indirect
 	github.com/pjbgf/sha1cd v0.5.0 // indirect
diff --git a/internal/chezmoi/format.go b/internal/chezmoi/format.go
index 341ac66c561..29af365695a 100644
--- a/internal/chezmoi/format.go
+++ b/internal/chezmoi/format.go
@@ -10,8 +10,8 @@ import (
 	"slices"
 	"strings"
 
+	"github.com/BurntSushi/toml"
 	"github.com/goccy/go-yaml"
-	"github.com/pelletier/go-toml/v2"
 	"github.com/tailscale/hujson"
 )
 
@@ -159,9 +159,8 @@ func (formatTOML) Name() string {
 
 // Unmarshal implements Format.Unmarshal.
 func (formatTOML) Unmarshal(data []byte, value any) error {
-	decoder := toml.NewDecoder(bytes.NewReader(data))
-	decoder.DisallowUnknownFields()
-	return decoder.Decode(value)
+	_, err := toml.Decode(string(data), value)
+	return err
 }
 
 // Name implements Format.Name.


Test patch:
diff --git a/internal/chezmoi/format_test.go b/internal/chezmoi/format_test.go
index f212c26c6bc..fdb39fd0854 100644
--- a/internal/chezmoi/format_test.go
+++ b/internal/chezmoi/format_test.go
@@ -148,6 +148,12 @@ func TestFormatEdgeCases(t *testing.T) {
 			data:     `key = "value"`,
 			expected: T{Key: "value"},
 		},
+		{
+			name:     "toml_1.1",
+			format:   FormatTOML,
+			data:     `key = "null byte: \x00; letter a: \x61"`,
+			expected: T{Key: "null byte: \x00; letter a: a"},
+		},
 		{
 			name:   "toml_empty",
 			format: FormatTOML,
@@ -158,17 +164,11 @@ func TestFormatEdgeCases(t *testing.T) {
 			data:     `key = "value"`,
 			expected: T{Key: "value"},
 		},
-		{
-			name:        "toml_unknown_field",
-			format:      FormatTOML,
-			data:        `unknown = "value"`,
-			expectedErr: "strict mode: fields in the document are missing in the target struct",
-		},
 		{
 			name:        "toml_unexpected_eof",
 			format:      FormatTOML,
 			data:        `[`,
-			expectedErr: "expected key but found none",
+			expectedErr: "unexpected end of table name",
 		},
 		{
 			name:   "toml_whitespace",
diff --git a/internal/cmd/testdata/scripts/init.txtar b/internal/cmd/testdata/scripts/init.txtar
index ebb0413d959..d42b2537a45 100644
--- a/internal/cmd/testdata/scripts/init.txtar
+++ b/internal/cmd/testdata/scripts/init.txtar
@@ -73,7 +73,7 @@ chhome home8/user
 # test that chezmoi init fails if the generated config is not valid
 mkgitconfig
 ! exec chezmoi init
-stderr 'toml: expected character ='
+stderr 'expected'
 ! exists .config/chezmoi
 
 chhome home/user