sipeed/picoclaw · error
start process hook: %w
Error message
start process hook: %w
What it means
Returned by NewProcessHook when isolation.Start(cmd) — the shared child-process isolation entry point that ultimately calls exec.Cmd.Start — cannot launch the hook command. This is the most common hook startup failure: the wrapped error tells you why (exec format, not found, permission, bad working dir, or sandbox denial).
Source
Thrown at pkg/agent/hook_process.go:130
if len(opts.Env) > 0 {
cmd.Env = append(os.Environ(), opts.Env...)
}
stdin, err := cmd.StdinPipe()
if err != nil {
return nil, fmt.Errorf("create process hook stdin: %w", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("create process hook stdout: %w", err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, fmt.Errorf("create process hook stderr: %w", err)
}
// Route hook subprocess startup through the shared isolation entry point so
// process hooks inherit the same isolation behavior as other child processes.
if err := isolation.Start(cmd); err != nil {
return nil, fmt.Errorf("start process hook: %w", err)
}
ph := &ProcessHook{
name: name,
opts: opts,
cmd: cmd,
stdin: stdin,
observeKinds: newProcessHookObserveKinds(opts.ObserveKinds),
pending: make(map[uint64]chan processHookRPCMessage),
done: make(chan struct{}),
}
go ph.readLoop(stdout)
go ph.readStderr(stderr)
go ph.waitLoop()
helloCtx := ctx
if helloCtx == nil {View on GitHub (pinned to 49183d7e8d)
Solutions
- Verify the command exists and is executable from the host process's cwd and PATH: use an absolute path in the hook config
- chmod +x the hook script and ensure scripts start with a valid shebang (#!/usr/bin/env ...)
- If opts.Dir is set, confirm that directory exists and is accessible
- If the isolation layer is active, check its log/config for a denial and allowlist the hook binary
Example fix
# before
hooks:
process:
my-hook:
command: ["./hooks/my-hook"] # relative, depends on cwd
# after
hooks:
process:
my-hook:
command: ["/opt/myapp/hooks/my-hook"] # absolute, executable Defensive patterns
Strategy: validation
Validate before calling
func validateHookCommand(spec config.ProcessHookConfig) error {
if len(spec.Command) == 0 {
return fmt.Errorf("hook command is required")
}
bin := spec.Command[0]
path := bin
if !filepath.IsAbs(path) {
var err error
path, err = exec.LookPath(bin)
if err != nil {
return fmt.Errorf("hook binary %q not found in PATH: %w", bin, err)
}
}
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("hook binary %q inaccessible: %w", path, err)
}
if info.Mode()&0111 == 0 {
return fmt.Errorf("hook binary %q is not executable", path)
}
if spec.Dir != "" {
if _, err := os.Stat(spec.Dir); err != nil {
return fmt.Errorf("hook dir %q invalid: %w", spec.Dir, err)
}
}
return nil
} Type guard
func isHookStartError(err error) bool {
return err != nil && strings.Contains(err.Error(), "start process hook:")
} Try / catch
ph, err := NewProcessHook(ctx, name, opts)
if err != nil {
if isHookStartError(err) {
// surface exec.ErrNotFound / permission errors with the binary path
return fmt.Errorf("failed to launch hook %q (%s): %w", name, opts.Command[0], err)
}
return err
} Prevention
- Use absolute paths for hook commands in deployed configs
- chmod +x hook scripts and verify shebangs in CI
- Smoke-test each hook binary from the same cwd/user the agent runs as
When it happens
Trigger: spec.Command[0] points to a binary that does not exist (exec: "...": executable file not found in $PATH), a file without the executable bit, a non-ELF script without a shebang, opts.Dir set to a nonexistent directory, or the isolation/sandbox layer refusing the spawn.
Common situations: Relative command path resolved against an unexpected cwd; forgetting chmod +x on a hook script; Windows line endings breaking a shebang; hook binary not shipped/installed on the deployment host; sandbox config (seccomp/landlock/container profile) blocking exec.
Related errors
- start process hook %q: %w
- Failed to start gateway: %v
- session not found
- session already completed
- failed to start editor: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/13d4f04ab2fb48f3.
Report an issue: GitHub.