sipeed/picoclaw · error

command is required

Error message

command is required

What it means

A process hook entry is enabled but its command array is empty — there is no executable to spawn. processHookOptionsFromConfig checks len(spec.Command) == 0 right after transport validation, so this is a pure config error caught before any process starts.

Source

Thrown at pkg/agent/hook_mount.go:231

	for name, spec := range specs {
		if spec.Enabled {
			names = append(names, name)
		}
	}
	sort.Strings(names)
	return names
}

func processHookOptionsFromConfig(spec config.ProcessHookConfig) (ProcessHookOptions, error) {
	transport := spec.Transport
	if transport == "" {
		transport = "stdio"
	}
	if transport != "stdio" {
		return ProcessHookOptions{}, fmt.Errorf("unsupported transport %q", transport)
	}
	if len(spec.Command) == 0 {
		return ProcessHookOptions{}, fmt.Errorf("command is required")
	}

	opts := ProcessHookOptions{
		Command: append([]string(nil), spec.Command...),
		Dir:     spec.Dir,
		Env:     processHookEnvFromMap(spec.Env),
	}

	observeKinds, observeEnabled, err := processHookObserveKindsFromConfig(spec.Observe)
	if err != nil {
		return ProcessHookOptions{}, err
	}
	opts.Observe = observeEnabled
	opts.ObserveKinds = observeKinds

	for _, intercept := range spec.Intercept {
		switch intercept {
		case "before_llm", "after_llm":

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Set command to the argv array of the hook process: ["/path/to/hook", "--flag"]
  2. Disable the entry (enabled=false) until the command exists
  3. Check config indentation so command sits under the correct process hook entry
  4. Re-check the field name is exactly 'command' (array form, not a shell string)

Example fix

// before
"processes": { "audit": { "enabled": true, "observe": ["*"] } }

// after
"processes": { "audit": { "enabled": true, "observe": ["*"],
  "command": ["/usr/local/bin/audit-hook"] } }
Defensive patterns

Strategy: validation

Validate before calling

for name, p := range cfg.Hooks.Processes {
    if p.Enabled && len(p.Command) == 0 {
        return fmt.Errorf("hooks.processes.%s: enabled without a command", name)
    }
}

Prevention

When it happens

Trigger: hooks.processes.<name>.enabled=true with the command key absent or set to [].

Common situations: Enabling a hook placeholder before its command is known; JSON/YAML indentation mistakes putting command at the wrong nesting level so it never lands on the hook spec; renaming the field (e.g. from cmd) during config migrations.

Related errors


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