sipeed/picoclaw · error

error loading config: %w

Error message

error loading config: %w

What it means

The skills command's PersistentPreRunE could not load picoclaw's configuration: internal.LoadConfig returned an error (malformed JSON, unreadable file, or failed validation), wrapped here. Every `picoclaw skills ...` subcommand aborts before its own logic runs.

Source

Thrown at cmd/picoclaw/internal/skills/command.go:27

	"github.com/sipeed/picoclaw/cmd/picoclaw/internal"
	"github.com/sipeed/picoclaw/pkg/skills"
)

type deps struct {
	workspace    string
	skillsLoader *skills.SkillsLoader
}

func NewSkillsCommand() *cobra.Command {
	var d deps

	cmd := &cobra.Command{
		Use:   "skills",
		Short: "Manage skills",
		PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
			cfg, err := internal.LoadConfig()
			if err != nil {
				return fmt.Errorf("error loading config: %w", err)
			}

			d.workspace = cfg.WorkspacePath()

			// get global config directory and builtin skills directory
			globalDir := filepath.Dir(internal.GetConfigPath())
			globalSkillsDir := filepath.Join(globalDir, "skills")
			builtinSkillsDir := filepath.Join(globalDir, "picoclaw", "skills")
			d.skillsLoader = skills.NewSkillsLoader(d.workspace, globalSkillsDir, builtinSkillsDir)

			return nil
		},
		RunE: func(cmd *cobra.Command, _ []string) error {
			return cmd.Help()
		},
	}

	loaderFn := func() (*skills.SkillsLoader, error) {

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Read the wrapped cause — it distinguishes JSON syntax errors from permission and validation failures.
  2. Validate the file mechanically (e.g. jq . <config.json>) and fix the reported syntax error.
  3. Check permissions/ownership on the config path picoclaw reports.
  4. If an upgrade changed the schema, re-init the config and re-apply your settings.

Example fix

// before: { "tools": { "skills": { "enabled": true, } } }  // trailing comma
// after:  { "tools": { "skills": { "enabled": true } } }
Defensive patterns

Strategy: validation

Validate before calling

raw, err := os.ReadFile(internal.GetConfigPath())
if err != nil {
    return fmt.Errorf("cannot read config: %w", err)
}
if !json.Valid(raw) {
    return fmt.Errorf("config %s is not valid JSON", internal.GetConfigPath())
}

Try / catch

cfg, err := internal.LoadConfig()
if err != nil {
    // surface the wrapped cause plus the config path so the user can fix it directly
    return fmt.Errorf("error loading config: %w (check %s)", err, internal.GetConfigPath())
}

Prevention

When it happens

Trigger: Running any `picoclaw skills` subcommand when the loaded config file is invalid JSON, unreadable due to permissions, or rejected by LoadConfig's validation (command.go:27).

Common situations: Hand-edited config.json with a trailing comma or unbalanced brace, file owned by root after a sudo run, or a config schema change after upgrading picoclaw.

Related errors


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