sipeed/picoclaw · error
failed to serialize config: %w
Error message
failed to serialize config: %w
What it means
json.Marshal of the normalized config failed (helpers.go:113-116). The config structs are plain data, so encoding/json only fails if a field type it cannot handle (chan, func, unsafe cyclic pointers) was introduced into config.Config — effectively a code regression in pkg/config, not a user-input problem.
Source
Thrown at cmd/picoclaw/internal/mcp/helpers.go:115
func loadConfig() (*config.Config, error) {
cfg, err := config.LoadConfig(internal.GetConfigPath())
if err != nil {
return nil, fmt.Errorf("failed to load config: %w", err)
}
return cfg, nil
}
func saveValidatedConfig(cfg *config.Config) error {
if cfg == nil {
return fmt.Errorf("config is nil")
}
normalizedCfg := normalizedConfigForSave(cfg)
data, err := json.Marshal(normalizedCfg)
if err != nil {
return fmt.Errorf("failed to serialize config: %w", err)
}
if err := validateConfigDocument(data); err != nil {
return err
}
if err := config.SaveConfig(internal.GetConfigPath(), normalizedCfg); err != nil {
return fmt.Errorf("failed to save config: %w", err)
}
return nil
}
func normalizedConfigForSave(cfg *config.Config) *config.Config {
clone := *cfg
if cfg.Tools.MCP.Servers == nil {
return &clone
}View on GitHub (pinned to 49183d7e8d)
Solutions
- Revert or redesign the offending field: keep config types to strings, numbers, bools, slices, and maps
- If a live object is needed, mark it json:"-" so it is excluded from serialization
Example fix
// before
type MCPServerConfig struct {
Client *mcp.Client `json:"client"` // cyclic/non-serializable
}
// after
type MCPServerConfig struct {
Client *mcp.Client `json:"-"` // excluded from config serialization
} Defensive patterns
Strategy: try-catch
Try / catch
if err := saveValidatedConfig(cfg); err != nil {
if strings.Contains(err.Error(), "failed to serialize config") {
// internal: a config field type broke encoding/json;
// fail loudly and file a bug rather than retrying
return fmt.Errorf("config struct no longer JSON-serializable: %w", err)
}
return err
} Prevention
- Keep config structs limited to JSON-native types; mark live objects json:"-"
- Add a round-trip unit test (Marshal then Unmarshal) for config types
When it happens
Trigger: Someone adds a func or channel field to Config/MCPConfig/MCPServerConfig; a cyclic reference is created between config types.
Common situations: Refactors of pkg/config that attach live objects (loggers, clients) instead of serializable settings.
Related errors
- failed to decode serialized config: %w
- Invalid JSON: %v
- marshal result: %w
- marshal request: %w
- parse response: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/da2d84514d2fd89c.
Report an issue: GitHub.