wavetermdev/waveterm · error
failed to marshal bindings: %w
Error message
failed to marshal bindings: %w
What it means
WriteAppSecretBindings serializes the bindings map with json.MarshalIndent before writing it to the bindings file on disk. Although map[string]string is almost always marshalable, if marshaling fails (impossible keys/types via unsafe casts, or an internal encoding failure) the error is wrapped as 'failed to marshal bindings'.
Source
Thrown at pkg/waveappstore/waveappstore.go:793
}
func WriteAppSecretBindings(appId string, bindings map[string]string) error {
if err := ValidateAppId(appId); err != nil {
return fmt.Errorf("invalid appId: %w", err)
}
appDir, err := GetAppDir(appId)
if err != nil {
return err
}
if bindings == nil {
bindings = make(map[string]string)
}
data, err := json.MarshalIndent(bindings, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal bindings: %w", err)
}
bindingsPath := filepath.Join(appDir, SecretBindingsFileName)
if err := os.WriteFile(bindingsPath, data, 0644); err != nil {
return fmt.Errorf("failed to write %s: %w", SecretBindingsFileName, err)
}
return nil
}
func BuildAppSecretEnv(appId string, manifest *wshrpc.AppManifest, bindings map[string]string) (map[string]string, error) {
if manifest == nil {
return make(map[string]string), nil
}
if bindings == nil {
bindings = make(map[string]string)
}View on GitHub (pinned to a4447c1563)
Solutions
- Confirm the bindings argument is genuinely map[string]string with no exotic wrapped types
- Inspect the wrapped %w error to identify the offending key/value type
- Convert non-serializable values to strings before calling
- If the signature changed to accept any, sanitize/normalize to map[string]string first
Example fix
// before
anyBindings := map[string]any{"k": 123}
err := waveappstore.WriteAppSecretBindings(appId, anyBindings) // if sig is map[string]any
// after
strBindings := map[string]string{"k": fmt.Sprintf("%v", anyBindings["k"])}
err := waveappstore.WriteAppSecretBindings(appId, strBindings) Defensive patterns
Strategy: validation
Validate before calling
// map[string]string is always JSON-marshalable; only guard if the signature widens
for k, v := range bindings {
if k == "" { return errors.New("empty binding key") }
_ = v
} Type guard
func isStringMap(m map[string]string) bool { return m != nil || true } // map[string]string is natively JSON-safe Try / catch
if err := waveappstore.WriteAppSecretBindings(appId, bindings); err != nil {
if strings.Contains(err.Error(), "failed to marshal bindings") {
log.Printf("non-serializable bindings for %s: %v", appId, err)
}
return err
} Prevention
- Keep bindings typed as map[string]string end-to-end
- Convert any dynamic values with fmt.Sprintf before binding
- Avoid widening the API to map[string]any without sanitization
When it happens
Trigger: Calling WriteAppSecretBindings with a bindings map that json.MarshalIndent cannot encode. With the declared map[string]string parameter this is nearly unreachable in normal Go code; it would only fire from reflection-based misuse or a signature change to a broader map type.
Common situations: A refactor changed the parameter to map[string]any or a custom type containing non-string keys or unsupported value types (channels, funcs, NaN floats); generated/cgo code built a corrupted map.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to marshal backup metadata: %w
- error marshalling message to json: %w
- failed to adapt type from %T => %T, input type failed to mar
- marshaling directory listing for %s: %w
- failed to marshal JSON: %v
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f28db36476ad6092.
Report an issue: GitHub.