sipeed/picoclaw · error
unsupported transport %q
Error message
unsupported transport %q
What it means
Process hooks communicate with picoclaw over their stdio; processHookOptionsFromConfig accepts only transport="stdio", treating an empty value as stdio. Any other value — "http", "grpc", "sse" — is rejected immediately at config-validation time, before the process is started.
Source
Thrown at pkg/agent/hook_mount.go:228
}
names := make([]string, 0, len(specs))
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
View on GitHub (pinned to 49183d7e8d)
Solutions
- Remove the transport field entirely — stdio is the default
- Or set it explicitly to "stdio"
- If you need a remote hook, run a small local stdio shim that forwards to your remote service
Example fix
// before
"processes": { "audit": { "enabled": true, "transport": "http", "command": ["/opt/audit"] } }
// after
"processes": { "audit": { "enabled": true, "command": ["/opt/audit"] } } Defensive patterns
Strategy: validation
Validate before calling
for name, p := range cfg.Hooks.Processes {
if p.Enabled && p.Transport != "" && p.Transport != "stdio" {
return fmt.Errorf("hooks.processes.%s: transport %q unsupported (only stdio)", name, p.Transport)
}
} Prevention
- Omit the transport field — stdio is the default and the only supported value
- Do not copy transport blocks from tools.mcp server configs into hooks.processes
- For remote hooks, deploy a local stdio shim process instead of a transport value
When it happens
Trigger: hooks.processes.<name>.transport set to any string other than "stdio" (or omitted). E.g. a config written assuming MCP-style network transports apply to hooks.
Common situations: Copy-pasting transport concepts from tools.mcp servers (which do support sse/http) into hooks.processes; future-proofing configs with speculative values; docs from a different hook system.
Related errors
- configure process hook %q: %w
- command is required
- builtin hook %q is not registered
- build builtin hook %q: %w
- start process hook %q: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/59fdcc46f5e8e2ef.
Report an issue: GitHub.