{"record":{"id":"ad647e3404049f78","repo":"paperclipai/paperclip","slug":"runtime-command-json-has-empty-command","errorCode":null,"errorMessage":"runtime-command.json has empty 'command'","messagePattern":"runtime-command\\.json has empty 'command'","errorType":"exception","errorClass":"error","httpStatus":null,"severity":"critical","filePath":"tools/agent-shim/runtime_command.go","lineNumber":26,"sourceCode":"\ntype RuntimeCommandSpec struct {\n\tCommand        string   `json:\"command\"`\n\tArgs           []string `json:\"args\"`\n\tDetectCommand  string   `json:\"detectCommand,omitempty\"`\n\tInstallCommand string   `json:\"installCommand,omitempty\"`\n}\n\nfunc loadRuntimeCommandSpec(path string) (*RuntimeCommandSpec, error) {\n\tb, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar spec RuntimeCommandSpec\n\tif err := json.Unmarshal(b, &spec); err != nil {\n\t\treturn nil, err\n\t}\n\tif spec.Command == \"\" {\n\t\treturn nil, errors.New(\"runtime-command.json has empty 'command'\")\n\t}\n\treturn &spec, nil\n}\n","sourceCodeStart":8,"sourceCodeEnd":30,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/tools/agent-shim/runtime_command.go#L8-L30","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// /run/paperclip/runtime-command.json\n{ \"command\": \"\", \"args\": [] }\n\n// after\n{ \"command\": \"claude\", \"args\": [] }","handlingStrategy":"validation","validationCode":"func validateRuntimeCommandSpec(spec *RuntimeCommandSpec) error {\n    if spec == nil || spec.Command == \"\" {\n        return errors.New(\"runtime-command.json requires a non-empty 'command'\")\n    }\n    return nil\n}\n// call after loadRuntimeCommandSpec and before exec.LookPath.","typeGuard":"func isValidCommandSpec(s *RuntimeCommandSpec) bool {\n    return s != nil && s.Command != \"\"\n}","tryCatchPattern":"spec, err := loadRuntimeCommandSpec(*specPath)\nif err != nil {\n    if strings.Contains(err.Error(), \"empty 'command'\") {\n        // regenerate the spec from the control plane, then retry once\n        if regenErr := regenerateSpec(*specPath); regenErr != nil {\n            fmt.Fprintf(os.Stderr, \"[shim] regen failed: %v\\n\", regenErr)\n            os.Exit(2)\n        }\n        spec, err = loadRuntimeCommandSpec(*specPath)\n    }\n    if err != nil {\n        os.Exit(2)\n    }\n}","preventionTips":["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."],"tags":["agent-shim","go","config","runtime-command","boot","adapter"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}