Summary
Encoder.SetIndent panics when called with a negative number of spaces. The doc comment does not mention this panic, so callers have no way to discover this behavior without reading the source. Since v4 is still a release candidate, this is a good time to consider returning an error instead.
Reproduction
Confirmed on go.yaml.in/yaml/v4 v4.0.0-rc.4, Go 1.25.1, darwin/arm64.
package main
import (
"bytes"
"go.yaml.in/yaml/v4"
)
func main() {
var buf bytes.Buffer
enc := yaml.NewEncoder(&buf)
enc.SetIndent(-1)
// panic: yaml: cannot indent to a negative number of spaces
}
Current Source (yaml.go ~line 547)
// SetIndent changes the used indentation used when encoding.
func (e *Encoder) SetIndent(spaces int) {
if spaces < 0 {
panic("yaml: cannot indent to a negative number of spaces")
}
e.encoder.Indent = spaces
}
The doc comment says only "SetIndent changes the used indentation used when encoding." — no mention of panic behavior.
Why This Matters
- Downstream impact already observed. The
yq tool has mikefarah/yq#2329 where yq -I=-1 produces a raw panic stacktrace because the value is passed through to SetIndent. End users see a crash instead of a meaningful error.
- If
spaces comes from user input, configuration, or computation, a negative value crashes the entire program with no opportunity for the caller to handle it gracefully.
- The Go standard library is inconsistent here —
text/tabwriter.Init panics on negative values (also undocumented), but encoding/json.Encoder.SetIndent does no validation at all. Neither is ideal; returning an error is the most composable option for a library.
Suggested Fix
Since v4 has not yet reached stable, the signature can still change without breaking semver:
Option A — Return an error (preferred):
func (e *Encoder) SetIndent(spaces int) error {
if spaces < 0 {
return fmt.Errorf("yaml: cannot indent to a negative number of spaces")
}
e.encoder.Indent = spaces
return nil
}
Option B — Clamp to zero:
func (e *Encoder) SetIndent(spaces int) {
if spaces < 0 {
spaces = 0
}
e.encoder.Indent = spaces
}
Option C — At minimum, document the panic:
// SetIndent changes the used indentation used when encoding.
// It panics if spaces is negative.
func (e *Encoder) SetIndent(spaces int) {
Related
Environment
- yaml version: go.yaml.in/yaml/v4 v4.0.0-rc.4
- Go version: go1.25.1 darwin/arm64
Summary
Encoder.SetIndentpanics when called with a negative number of spaces. The doc comment does not mention this panic, so callers have no way to discover this behavior without reading the source. Since v4 is still a release candidate, this is a good time to consider returning an error instead.Reproduction
Confirmed on
go.yaml.in/yaml/v4 v4.0.0-rc.4, Go 1.25.1, darwin/arm64.Current Source (yaml.go ~line 547)
The doc comment says only "SetIndent changes the used indentation used when encoding." — no mention of panic behavior.
Why This Matters
yqtool has mikefarah/yq#2329 whereyq -I=-1produces a raw panic stacktrace because the value is passed through toSetIndent. End users see a crash instead of a meaningful error.spacescomes from user input, configuration, or computation, a negative value crashes the entire program with no opportunity for the caller to handle it gracefully.text/tabwriter.Initpanics on negative values (also undocumented), butencoding/json.Encoder.SetIndentdoes no validation at all. Neither is ideal; returning an error is the most composable option for a library.Suggested Fix
Since v4 has not yet reached stable, the signature can still change without breaking semver:
Option A — Return an error (preferred):
Option B — Clamp to zero:
Option C — At minimum, document the panic:
Related
Environment