sipeed/picoclaw · error
mount process hook %q: %w
Error message
mount process hook %q: %w
What it means
Identical failure surface to the builtin-hook mount error, but for process hooks: after NewProcessHook succeeds, AgentLoop.MountHook -> HookManager.Mount failed (nil hook manager, empty name, or nil hook). On this path the just-started subprocess is Closed before returning, so no orphan process leaks. Realistic cause is an AgentLoop built without a HookManager.
Source
Thrown at pkg/agent/hook_mount.go:184
for _, name := range processNames {
spec := al.cfg.Hooks.Processes[name]
opts, buildErr := processHookOptionsFromConfig(spec)
if buildErr != nil {
return fmt.Errorf("configure process hook %q: %w", name, buildErr)
}
processHook, buildErr := NewProcessHook(ctx, name, opts)
if buildErr != nil {
return fmt.Errorf("start process hook %q: %w", name, buildErr)
}
if err := al.MountHook(HookRegistration{
Name: name,
Priority: spec.Priority,
Source: HookSourceProcess,
Hook: processHook,
}); err != nil {
_ = processHook.Close()
return fmt.Errorf("mount process hook %q: %w", name, err)
}
mounted = append(mounted, name)
}
return nil
}
func enabledBuiltinHookNames(specs map[string]config.BuiltinHookConfig) []string {
if len(specs) == 0 {
return nil
}
names := make([]string, 0, len(specs))
for name, spec := range specs {
if spec.Enabled {
names = append(names, name)
}
}View on GitHub (pinned to 49183d7e8d)
Solutions
- Build the AgentLoop with the standard constructor so a HookManager exists
- Set hooks.enabled=false in configs used with hook-less loops
- In tests, use the full constructor or trim the config's hooks section
- Check the wrapped message ('hook manager is not initialized') to confirm wiring is the problem
Defensive patterns
Strategy: try-catch
Try / catch
if err := al.MountHook(reg); err != nil {
if strings.Contains(err.Error(), "hook manager is not initialized") {
// process already Closed by the caller; rebuild loop wiring, do not retry
return fmt.Errorf("loop constructed without hook manager: %w", err)
}
return err
} Prevention
- Use the standard AgentLoop constructor whenever hooks are enabled
- Keep test configs hook-free when the test loop lacks a HookManager
- Note the caller closes the subprocess on mount failure — no leak to clean up, just fix wiring and restart
When it happens
Trigger: hooks.processes.<name> starts fine but MountHook fails because al.hooks is nil — custom/hand-built AgentLoop (tests, forks) with hooks.enabled=true and a process hook enabled in config.
Common situations: Test harnesses constructing AgentLoop structs directly; forks with partial construction; hook manager deliberately omitted while hooks remain enabled in config.
Related errors
- mount builtin hook %q: %w
- configure process hook %q: %w
- start process hook %q: %w
- unsupported transport %q
- command is required
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/800e6cc29dbd5e89.
Report an issue: GitHub.