dagger/dagger · error
serialize user config: %w
Error message
serialize user config: %w
What it means
After writing a value into the TOML tree at [workspaces.<workspaceKey>], WriteUserConfigValue serializes the tree back to TOML with tree.ToTomlString(). This error wraps serialization failure — typically a value type the TOML writer cannot represent (maps with mixed types, unsupported primitives, empty map keys) inserted at the computed path.
Source
Thrown at core/workspace/userconfig.go:273
if err != nil {
return nil, err
}
tree, entryKey, err := userConfigTreeAndEntryKey(existing, workspaceKey)
if err != nil {
return nil, err
}
var value any
if values != nil {
value = values
} else {
value = parseValueString(parts, rawValue)
}
tree.SetPath(append([]string{"workspaces", entryKey}, parts...), value)
out, err := tree.ToTomlString()
if err != nil {
return nil, fmt.Errorf("serialize user config: %w", err)
}
return []byte(out), nil
}
// DeleteUserConfigValue removes a config value under
// [workspaces.<workspaceKey>] in user-level config bytes, pruning any tables
// the removal leaves empty. It errors when the key is not set for that
// workspace.
func DeleteUserConfigValue(existing []byte, workspaceKey, key string) ([]byte, error) {
parts, err := userOverlayKeyParts(key)
if err != nil {
return nil, err
}
tree, entryKey, err := userConfigTreeAndEntryKey(existing, workspaceKey)
if err != nil {
return nil, err
}
View on GitHub (pinned to 82ba2681db)
Solutions
- Pass a scalar value (string, number, bool) or ensure the raw value parses to a TOML-compatible type
- Quote or normalize the workspace entry key so it forms a valid TOML table name
- Inspect the wrapped inner error for the offending path/type and adjust the value
- If writing structured data, store it as a JSON string in a settings value instead of a nested table
Example fix
// before
WriteUserConfigValue(data, key, "{a: 1}") // unparseable structure
// after
WriteUserConfigValue(data, key, "30") // scalar value serializes cleanly Defensive patterns
Strategy: validation
Validate before calling
v := parseValueString(parts, raw)
switch v.(type) {
case string, int64, float64, bool:
default:
return fmt.Errorf("value %v is not TOML-serializable", raw)
} Type guard
func tomlSafeValue(v any) bool {
switch v.(type) { case string, int64, float64, bool: return true }; return false
} Try / catch
out, err := workspace.WriteUserConfigValue(data, key, wsKey, raw)
if err != nil && strings.Contains(err.Error(), "serialize user config") {
// retry with a stringified scalar value
out, err = workspace.WriteUserConfigValue(data, key, wsKey, fmt.Sprintf("%v", raw))
} Prevention
- Write only scalar values through the settings API
- Quote workspace keys containing special characters when hand-editing TOML
- Round-trip test: parse the output TOML after every programmatic write
When it happens
Trigger: WriteUserConfigValue called with a rawValue that parses (via parseValueString) into a TOML-incompatible value, then tree.ToTomlString() fails; also triggered by an entryKey or key path containing segments the TOML writer cannot render as table names.
Common situations: Passing JSON-like nested structures as raw values that don't round-trip through TOML; workspace keys containing characters that produce invalid TOML table headers; writing values via scripting with unquoted special characters.
Related errors
- failed to marshal config: %w
- failed to serialize config: %w
- render config after delete: %w
- format config after as-sdk rewrite: %w
- serializing workspace config: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/538939704baba35c.
Report an issue: GitHub.