{"record":{"id":"73fe4de57d27dd2b","repo":"hashicorp/nomad","slug":"command-is-required","errorCode":null,"errorMessage":"command is required","messagePattern":"command is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/shared/executor/executor.go","lineNumber":499,"sourceCode":"\n\t\t// Some kind of error happened; default to critical\n\t\texitCode := 2\n\t\tif status, ok := exitErr.Sys().(syscall.WaitStatus); ok {\n\t\t\texitCode = status.ExitStatus()\n\t\t}\n\n\t\t// Don't return the exitError as the caller only needs the\n\t\t// output and code.\n\t\treturn buf.Bytes(), exitCode, nil\n\t}\n\treturn buf.Bytes(), 0, nil\n}\n\nfunc (e *UniversalExecutor) ExecStreaming(ctx context.Context, command []string, tty bool,\n\tstream drivers.ExecTaskStream) error {\n\n\tif len(command) == 0 {\n\t\treturn fmt.Errorf(\"command is required\")\n\t}\n\n\tcmd := exec.CommandContext(ctx, command[0], command[1:]...)\n\n\tcmd.Dir = e.childCmd.Dir\n\tcmd.Env = e.childCmd.Env\n\n\texecHelper := &execHelper{\n\t\tlogger: e.logger,\n\n\t\tnewTerminal: func() (func() (*os.File, error), *os.File, error) {\n\t\t\tpty, tty, err := pty.Open()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\n\t\t\treturn func() (*os.File, error) { return pty, nil }, tty, err\n\t\t},","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/shared/executor/executor.go#L481-L517","documentation":"UniversalExecutor.ExecStreaming validates that the command slice passed for streaming execution is non-empty. An empty command means exec.CommandContext would have no binary to run, so the executor rejects it up front with this error instead of failing later in exec. It is a programmer/config error guard at the entry of the streaming exec API.","triggerScenarios":"Calling ExecStreaming(ctx, nil/[]string{}, tty, stream) or passing a command slice that was produced empty by upstream config parsing (e.g. raw_exec command string split produced no tokens).","commonSituations":"Job/task config with an empty 'command' field; splitting a command string on whitespace where the string is blank; templating that rendered an empty command; tests that forget to populate command.","solutions":["Ensure the command slice has at least one element before calling ExecStreaming","If building from a string, trim and validate the string is non-empty before splitting","Log the task config that produced the empty command to find the upstream parsing bug"],"exampleFix":"// before\nexec.ExecStreaming(ctx, cfg.Command, tty, stream) // cfg.Command may be empty\n// after\nif len(cfg.Command) == 0 {\n    return fmt.Errorf(\"task command is empty; check job config\")\n}\nreturn exec.ExecStreaming(ctx, cfg.Command, tty, stream)","handlingStrategy":"validation","validationCode":"if len(command) == 0 {\n    return fmt.Errorf(\"cannot exec: command slice is empty\")\n}\nreturn e.ExecStreaming(ctx, command, tty, stream)","typeGuard":"func hasCommand(cmd []string) bool { return len(cmd) > 0 }","tryCatchPattern":"if err := e.ExecStreaming(ctx, command, tty, stream); err != nil {\n    if strings.Contains(err.Error(), \"command is required\") {\n        // fix caller config; no retry will help\n        return fmt.Errorf(\"invalid exec request: %w\", err)\n    }\n    return err\n}","preventionTips":["Validate the command field at job/config parse time","Never pass a raw split of an untrimmed string as command","Add unit tests covering empty-command inputs"],"tags":["executor","validation","exec"],"backgroundTag":"empty-command-argument","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}