sipeed/picoclaw · error
failed to save config: %w
Error message
failed to save config: %w
What it means
picoclaw model add successfully upserted the model entry in memory and set the default model name, but config.SaveConfig failed to persist it — so nothing was written. The wrapped error carries the cause: marshaling or save-time validation failure, permission denied on the file or directory, a read-only filesystem, or disk full.
Source
Thrown at cmd/picoclaw/internal/model/add.go:195
m.Enabled = true
found = true
break
}
}
if !found {
cfg.ModelList = append(cfg.ModelList, &config.ModelConfig{
ModelName: alias,
Model: modelID,
APIBase: apiBase,
APIKeys: secureKeys,
Enabled: true,
})
}
cfg.Agents.Defaults.ModelName = alias
if err := config.SaveConfig(configPath, cfg); err != nil {
return fmt.Errorf("failed to save config: %w", err)
}
fmt.Fprintf(stdout, "✓ Saved model '%s' (%s) and set as default.\n", alias, modelID)
return nil
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Read the wrapped error: 'permission denied' → chown the config file and its directory to the current user; 'no space left on device' → free space
- After earlier sudo runs, fix ownership: sudo chown -R $(id -u):$(id -g) <config-dir>
- Re-run the command once fixed — since the save failed, there is no partial state to clean up
- For validation failures, fix the field named in the error and retry
Example fix
# before $ picoclaw model add -b ... -k ... -m gpt-4o-mini failed to save config: ... permission denied # after $ sudo chown -R $(id -u):$(id -g) ~/.config/picoclaw $ picoclaw model add -b ... -k ... -m gpt-4o-mini
Defensive patterns
Strategy: try-catch
Validate before calling
configPath := internal.GetConfigPath()
f, err := os.OpenFile(configPath, os.O_WRONLY|os.O_APPEND, 0)
if err != nil {
return fmt.Errorf("config %s not writable: %w", configPath, err)
}
f.Close() Type guard
func isConfigSaveError(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to save config")
}
func isPermissionErr(err error) bool {
return errors.Is(err, os.ErrPermission) // through the %w chain
} Try / catch
if err := config.SaveConfig(configPath, cfg); err != nil {
if errors.Is(err, os.ErrPermission) {
// guide: chown the config dir, or rerun with corrected ownership; state was not persisted
}
if errors.Is(err, fs.ErrNoSpace) {
// alert on disk space; safe to retry after cleanup
}
return fmt.Errorf("failed to save config: %w", err)
} Prevention
- Never alternate sudo and non-sudo picoclaw runs against one config
- Check writability of the config path in setup scripts
- Keep disk headroom on machines that write configs frequently
When it happens
Trigger: Config file or its directory owned by root after earlier sudo use while now running as a normal user; read-only mount (container, WSL); disk-full; a config state that fails picoclaw's save-time validation.
Common situations: Mixed sudo/non-sudo invocations leaving root-owned config files; containers with read-only home; CI runners out of disk; configs with fields that fail validation on write.
Related errors
- failed to save config: %w
- failed to load config: %w
- reset failed: %w
- error adding job: %w
- failed to load config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/283076469fa54d4b.
Report an issue: GitHub.