paperclipai/paperclip · critical · error
runtime-command.json has empty 'command'
Error message
runtime-command.json has empty 'command'
What it means
Returned by loadRuntimeCommandSpec in the agent-shim after the runtime-command.json file is found and parsed as JSON, but its 'command' field is the empty string (or missing, which decodes to ''). The shim then cannot exec.LookPath any binary, so it rejects the spec immediately; main.go prints the error and exits with code 2. Args, detectCommand, and installCommand are all optional; only command is required.
Source
Thrown at tools/agent-shim/runtime_command.go:26
type RuntimeCommandSpec struct {
Command string `json:"command"`
Args []string `json:"args"`
DetectCommand string `json:"detectCommand,omitempty"`
InstallCommand string `json:"installCommand,omitempty"`
}
func loadRuntimeCommandSpec(path string) (*RuntimeCommandSpec, error) {
b, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var spec RuntimeCommandSpec
if err := json.Unmarshal(b, &spec); err != nil {
return nil, err
}
if spec.Command == "" {
return nil, errors.New("runtime-command.json has empty 'command'")
}
return &spec, nil
}
View on GitHub (pinned to 67001ec6eb)
Solutions
- Regenerate /run/paperclip/runtime-command.json with a non-empty command (the adapter binary name, e.g. 'claude', 'codex').
- Verify the writer that produces the spec resolves the adapter command before writing the file; fail fast upstream if it is empty.
- Inspect the spec file (cat the path) to confirm command is populated; the shim accepts absolute or PATH-resolved names.
Example fix
// before
// /run/paperclip/runtime-command.json
{ "command": "", "args": [] }
// after
{ "command": "claude", "args": [] } Defensive patterns
Strategy: validation
Validate before calling
func validateRuntimeCommandSpec(spec *RuntimeCommandSpec) error {
if spec == nil || spec.Command == "" {
return errors.New("runtime-command.json requires a non-empty 'command'")
}
return nil
}
// call after loadRuntimeCommandSpec and before exec.LookPath. Type guard
func isValidCommandSpec(s *RuntimeCommandSpec) bool {
return s != nil && s.Command != ""
} Try / catch
spec, err := loadRuntimeCommandSpec(*specPath)
if err != nil {
if strings.Contains(err.Error(), "empty 'command'") {
// regenerate the spec from the control plane, then retry once
if regenErr := regenerateSpec(*specPath); regenErr != nil {
fmt.Fprintf(os.Stderr, "[shim] regen failed: %v\n", regenErr)
os.Exit(2)
}
spec, err = loadRuntimeCommandSpec(*specPath)
}
if err != nil {
os.Exit(2)
}
} Prevention
- Have the spec writer fail fast when the adapter command is empty rather than emitting an empty field.
- Validate the JSON template at generation time; treat empty command as a writer bug.
- Unit-test main_test.go table with an empty-command fixture to lock the failure shape.
When it happens
Trigger: The runtime-command.json written under /run/paperclip/ (or the -spec path) contains {"command":"","args":[...]} or is missing the command field entirely; the file is generated by a control-plane step that failed to fill in the adapter binary name.
Common situations: Control-plane bug that writes the spec before resolving the adapter command; a templated spec whose ${ADAPTER_COMMAND} variable expanded to empty; a hand-edited spec left with a blank command during debugging; a stale spec file left over from a previous, different adapter.
Related errors
- Failed to parse JSON at ${filePath}: ${err instanceof Error
- Company ID is required. Pass --company-id, set PAPERCLIP_COM
- Company ID is required. Pass --company-id, set PAPERCLIP_COM
- Company ID is required. Pass --company-id, set PAPERCLIP_COM
- Embedded PostgreSQL support requires dependency `embedded-po
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/ad647e3404049f78.
Report an issue: GitHub.