{"record":{"id":"30bcd003c06a8626","repo":"hashicorp/nomad","slug":"need-an-executable-to-run","errorCode":null,"errorMessage":"need an executable to run","messagePattern":"need an executable to run","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/var_lock.go","lineNumber":350,"sourceCode":"\n\treturn path, args, nil\n}\n\n// script returns a command to execute a script through a shell.\nfunc script(ctx context.Context, args []string) (*exec.Cmd, error) {\n\tshell := \"/bin/sh\"\n\n\tif other := os.Getenv(\"SHELL\"); other != \"\" {\n\t\tshell = other\n\t}\n\n\treturn exec.CommandContext(ctx, shell, \"-c\", strings.Join(args, \" \")), nil\n}\n\n// subprocess returns a command to execute a subprocess directly.\nfunc subprocess(ctx context.Context, args []string) (*exec.Cmd, error) {\n\tif len(args) == 0 {\n\t\treturn nil, fmt.Errorf(\"need an executable to run\")\n\t}\n\treturn exec.CommandContext(ctx, args[0], args[1:]...), nil\n}\n\n// ForwardSignals will fire up a goroutine to forward signals to the given\n// subprocess until the context is canceled.\nfunc (c *VarLockCommand) forwardSignals(ctx context.Context, cmd *exec.Cmd, sg chan os.Signal) {\n\tfor {\n\t\tselect {\n\t\tcase sig := <-sg:\n\t\t\tif err := cmd.Process.Signal(sig); err != nil {\n\t\t\t\tc.varPutCommand.Ui.Error(fmt.Sprintf(\"failed to send signal %q: %v\", sig, err))\n\t\t\t}\n\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\t}\n\t}","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/var_lock.go#L332-L368","documentation":"The `subprocess` helper builds an exec.Cmd to run an executable directly (as opposed to through a shell). It refuses to build a command when the args slice is empty, since there is no binary name to execute. This guards against silently launching nothing after argument parsing.","triggerScenarios":"Calling code that resolves the subprocess command (e.g. `nomad var lock`'s command-execution path, or Run forwarding remaining args) passes an empty args slice to subprocess — typically when the user provided no command after flags, or flag parsing consumed everything.","commonSituations":"Running `nomad var lock <path>` without the trailing `-- <command>`; a script variable holding the command name expands to empty; quoting mistakes cause the shell to pass zero arguments to the lock subcommand.","solutions":["Supply the executable to run under the lock: `nomad var lock <path> -- <command> [args...]`.","Check the script for an unset/empty variable that was meant to hold the command name.","If the command is optional, guard the invocation and skip the lock subcommand when no command is given."],"exampleFix":"// before\nnomad var lock nomad/jobs/web\n// after\nnomad var lock nomad/jobs/web -- ./deploy.sh","handlingStrategy":"validation","validationCode":"if [ -z \"${CMD:-}\" ]; then echo \"usage: nomad var lock <path> -- <command> [args...]\" >&2; exit 2; fi","typeGuard":null,"tryCatchPattern":"err := cmd.Run()\nif err != nil && strings.Contains(err.Error(), \"need an executable to run\") {\n    log.Fatal(\"no command supplied after '--' to run under the lock\")\n}","preventionTips":["Always pass the command to run after `--` when using var lock.","Quote script variables that expand to command names: \"${CMD}\".","Fail early in wrappers if the command argument is empty."],"tags":["cli","exec","nomad","arguments"],"backgroundTag":"missing-executable-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"}