{"record":{"id":"97cebf4d04a213d7","repo":"GoogleContainerTools/skaffold","slug":"starting-cmd-w","errorCode":null,"errorMessage":"starting cmd: %w","messagePattern":"starting cmd: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/hooks/host.go","lineNumber":56,"sourceCode":"}\n\ntype Skip struct{}\n\nfunc (e *Skip) Error() string {\n\treturn \"host hook execution skipped.\"\n}\n\n// run executes the lifecycle hook on the host machine\nfunc (h hostHook) run(ctx context.Context, in io.Reader, out io.Writer) error {\n\tif len(h.cfg.OS) > 0 && !stringslice.Contains(h.cfg.OS, runtime.GOOS) {\n\t\tlog.Entry(ctx).Infof(\"host hook execution skipped due to OS criteria %q not matched for commands:\\n%q\\n\", strings.Join(h.cfg.OS, \",\"), strings.Join(h.cfg.Command, \" \"))\n\t\treturn &Skip{}\n\t}\n\tcmd := h.retrieveCmd(ctx, in, out)\n\n\tlog.Entry(ctx).Debugf(\"Running command: %s\", cmd.Args)\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"starting cmd: %w\", err)\n\t}\n\treturn misc.HandleGracefulTermination(ctx, cmd)\n}\n\nfunc (h hostHook) retrieveCmd(ctx context.Context, in io.Reader, out io.Writer) *exec.Cmd {\n\tcmd := exec.CommandContext(ctx, h.cfg.Command[0], h.cfg.Command[1:]...)\n\tif in != nil {\n\t\tcmd.Stdin = in\n\t}\n\tcmd.Stdout = out\n\tcmd.Stderr = out\n\tcmd.Env = append(cmd.Env, h.env...)\n\tcmd.Env = append(cmd.Env, util.OSEnviron()...)\n\tcmd.Dir = h.cfg.Dir\n\n\treturn cmd\n}\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/hooks/host.go#L38-L74","documentation":"hostHook.run executes a lifecycle hook as a local process. It builds the exec.Cmd via retrieveCmd and calls cmd.Start(); if the process cannot be started (binary not found, not executable, permission denied), the error is wrapped as 'starting cmd: %w'. Note: successful Start is then followed by misc.HandleGracefulTermination for Wait.","triggerScenarios":"run (called by RunPostHooks) invoking cmd.Start() when h.cfg.Command[0] does not exist on PATH, is not executable, or the OS refuses to spawn the process.","commonSituations":"Host hook command specified with a relative path not on PATH; script without the executable bit; command present in the dev container but not on the host machine; typo in the binary name in skaffold.yaml hostHooks.","solutions":["Verify the command exists and is executable: which <cmd> / chmod +x <script>","Use an absolute path (e.g. /bin/sh) or invoke via 'sh -c' in the hook command","Test the command manually from the same environment skaffold runs in","Fix the command array in skaffold.yaml hostHooks (args split correctly)"],"exampleFix":"// before\nhostHooks:\n  postRender:\n    - command: [\"notify.sh\"]   # not on PATH, not executable\n// after\nhostHooks:\n  postRender:\n    - command: [\"/bin/sh\", \"-c\", \"./scripts/notify.sh\"]  # with chmod +x scripts/notify.sh","handlingStrategy":"validation","validationCode":"bin := h.cfg.Command[0]\nif _, err := exec.LookPath(bin); err != nil {\n    return fmt.Errorf(\"host hook command %q not found on PATH\", bin)\n}","typeGuard":null,"tryCatchPattern":"err := hook.Run(ctx, out)\nif err != nil && strings.Contains(err.Error(), \"starting cmd\") {\n    return fmt.Errorf(\"host hook failed to start; check command exists and is executable: %w\", err)\n}","preventionTips":["Use absolute paths or 'sh -c' wrappers for host hook commands","chmod +x any script referenced by a hook","Mirror the dev environment: test hooks where skaffold actually runs","Keep the command array split into binary + args correctly"],"tags":["exec","process","hooks","command-not-found"],"backgroundTag":"command-not-found","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}