sipeed/picoclaw · error

failed to load config: %w

Error message

failed to load config: %w

What it means

loadConfig (helpers.go:98-104) wraps config.LoadConfig(internal.GetConfigPath()); it fails when the config file is missing at the expected path, unreadable, or unparseable. Every mcp subcommand that touches persisted state (add, edit, list, remove) starts here, so this error surfaces before any subcommand logic runs.

Source

Thrown at cmd/picoclaw/internal/mcp/helpers.go:101

              }
            }
          },
          "required": ["enabled"],
          "additionalProperties": true
        }
      },
      "required": ["mcp"],
      "additionalProperties": true
    }
  },
  "required": ["tools"],
  "additionalProperties": true
}`

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

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Locate the expected file via the CLI's config path and lint it as JSON (e.g. jq . file >/dev/null) to find the syntax error
  2. Restore from a backup, or move the broken file aside so picoclaw recreates a default on next run
  3. Check read permission on the file and every parent directory

Example fix

# before: config has a trailing comma
# after: valid JSON
# { "tools": { "mcp": { "enabled": true, "servers": {} } } }
Defensive patterns

Strategy: try-catch

Validate before calling

cfgPath=$(picoclaw config path 2>/dev/null || echo "$HOME/.config/picoclaw/config.json")
jq . "$cfgPath" >/dev/null || { echo "config is not valid JSON" >&2; exit 1; }

Try / catch

if err := cmd.Execute(); err != nil {
	if strings.Contains(err.Error(), "failed to load config") {
		// err wraps the underlying *fs.PathError / json syntax error via %w
		fmt.Fprintf(os.Stderr, "config problem: %v\n", errors.Unwrap(err))
	}
}

Prevention

When it happens

Trigger: Config file deleted/renamed; JSON syntax error from a previous manual edit; unreadable permissions; a config-path override pointing at a nonexistent file.

Common situations: Hand-editing and leaving a trailing comma; dotfile sync between machines with different XDG paths; another tool rewriting the config and corrupting it.

Related errors


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