sipeed/picoclaw · error

failed to save config: %w

Error message

failed to save config: %w

What it means

picoclaw model <alias> validated the alias and updated cfg.Agents.Defaults.ModelName in memory, but config.SaveConfig failed to write the file — no change was persisted. The wrapped error names the cause: permission denied, read-only filesystem, disk full, or a save-time validation/marshal failure.

Source

Thrown at cmd/picoclaw/internal/model/command.go:124

		if model.Enabled && model.ModelName == modelName {
			modelFound = true
			break
		}
	}

	if !modelFound && modelName != LocalModel {
		return fmt.Errorf("cannot found model '%s' in config", modelName)
	}

	// Update the default model
	// Clear old model field and set new model_name
	oldModel := cfg.Agents.Defaults.ModelName

	cfg.Agents.Defaults.ModelName = modelName

	// Save config back to file
	if err := config.SaveConfig(configPath, cfg); err != nil {
		return fmt.Errorf("failed to save config: %w", err)
	}

	fmt.Printf("✓ Default model changed from '%s' to '%s'\n",
		formatModelName(oldModel), modelName)
	fmt.Println("\nThe new default model will be used for all agent interactions.")

	return nil
}

func formatModelName(name string) string {
	if name == "" {
		return "(none)"
	}
	return name
}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Read the wrapped error: 'permission denied' → sudo chown -R $(id -u):$(id -g) <config-dir>; 'no space left' → free space
  2. Re-run picoclaw model <alias> after fixing — the failed save left no partial state
  3. For validation failures, fix the field named in the error
  4. Avoid mixing sudo and non-sudo picoclaw invocations against the same config

Example fix

# before
$ picoclaw model custom-prefer
failed to save config: ... permission denied

# after
$ sudo chown -R $(id -u):$(id -g) ~/.config/picoclaw
$ picoclaw model custom-prefer
Defensive patterns

Strategy: try-catch

Validate before calling

f, err := os.OpenFile(configPath, os.O_WRONLY|os.O_APPEND, 0)
if err != nil {
  return fmt.Errorf("config %s not writable: %w — fix ownership before changing models", configPath, err)
}
f.Close()

Type guard

func isConfigSaveError(err error) bool {
  return err != nil && strings.Contains(err.Error(), "failed to save config")
}

Try / catch

if err := config.SaveConfig(configPath, cfg); err != nil {
  if errors.Is(err, os.ErrPermission) {
    // nothing was persisted; fix chown/permissions, then re-run picoclaw model <alias>
  }
  return fmt.Errorf("failed to save config: %w", err)
}

Prevention

When it happens

Trigger: Config file or directory not writable by the current user (often after running picoclaw under sudo earlier); read-only mounts (containers, WSL); disk-full; config content failing save-time validation.

Common situations: Root-owned config from mixed sudo/non-sudo use; containers with read-only home; runners out of disk.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/c64153511a075e33. Report an issue: GitHub.