gastownhall/beads · warning
encoding string: %w
Error message
encoding string: %w
What it means
writeCanonicalMetadataString emits one JSON string (key or value) using the standard library's escaping via json.Marshal so both sides of a comparison escape identically. json.Marshal on a Go string cannot fail in current Go, so this error is defensive: it only fires if the standard library's marshaler returns an unexpected error, and it wraps it so the cause is preserved.
Source
Thrown at internal/storage/metadata_cas.go:221
if err := writeCanonicalMetadataJSON(buf, typed[key]); err != nil {
return err
}
}
buf.WriteByte('}')
default:
// encoding/json produces only the cases above for an `any` target with
// UseNumber set, so reaching this means the decoder changed under us.
return fmt.Errorf("cannot canonicalize %T", value)
}
return nil
}
// writeCanonicalMetadataString emits a JSON string with the standard library's
// escaping, which both sides of a comparison go through identically.
func writeCanonicalMetadataString(buf *bytes.Buffer, s string) error {
encoded, err := json.Marshal(s)
if err != nil {
return fmt.Errorf("encoding string: %w", err)
}
buf.Write(encoded)
return nil
}
// truncateMetadataValue bounds a malformed value quoted back at a caller, so a
// megabyte of junk does not become a megabyte of error message.
func truncateMetadataValue(raw json.RawMessage) string {
const limit = 64
if len(raw) <= limit {
return string(raw)
}
return string(raw[:limit]) + "…"
}
View on GitHub (pinned to 71377f2769)
Solutions
- Unwrap the error to read json.Marshal's underlying cause (check Go release notes for encoding/json behavior changes).
- Upgrade or pin the Go toolchain to a version where json.Marshal(string) is total.
- As a workaround, pre-encode the string yourself with json.Marshal and compare the encoded bytes.
- File an issue with the input string if a reproducible marshal failure exists.
Defensive patterns
Strategy: try-catch
Try / catch
if err := storage.CanonicalMetadataValue(raw); err != nil {
if strings.Contains(err.Error(), "encoding string") {
// standard-library marshal failure: report toolchain/runtime details
return fmt.Errorf("canonicalizer string encode failed (go %s): %w", runtime.Version(), err)
}
return err
} Prevention
- Treat any occurrence as a Go runtime/standard-library anomaly, not an input problem.
- Keep the Go toolchain patched; check encoding/json release notes when upgrading.
- Do not attempt to pre-escape strings yourself — the canonicalizer applies stdlib escaping to both comparison sides identically.
When it happens
Trigger: Effectively unreachable for plain string inputs — reached only through writeCanonicalMetadataJSON during CanonicalMetadataValue if json.Marshal(string) ever returned an error (e.g. a future Go change or an unsupported rune scenario in the runtime).
Common situations: Developers effectively never hit this in production; if it appears, it signals a Go runtime/standard-library anomaly or code drift in the canonicalizer (the sibling 'cannot canonicalize %T' branch guards similar drift).
Related errors
- ExternalDoltConfig: must set Socket or (Host, Port)
- metadata must be a JSON object: %w
- metadata.repo: %w
- metadata.repo must not be null
- metadata.repo must be a string, got %T
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/195ddbcf234500ca.
Report an issue: GitHub.