{"record":{"id":"ea942105188ee350","repo":"GoogleContainerTools/skaffold","slug":"failed-to-execute-host-s-hook-d-for-artifact-q","errorCode":null,"errorMessage":"failed to execute host %s hook %d for artifact %q: %w","messagePattern":"failed to execute host (.+?) hook (.+?) for artifact %q: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/hooks/sync.go","lineNumber":86,"sourceCode":"\treturn r.run(ctx, out, r.PostHooks, phases.PostSync)\n}\n\nfunc (r syncRunner) getEnv() []string {\n\tcommon := getEnv(staticEnvOpts)\n\tsync := getEnv(r.opts)\n\treturn append(common, sync...)\n}\n\nfunc (r syncRunner) run(ctx context.Context, out io.Writer, hooks []latest.SyncHookItem, phase phase) error {\n\tif len(hooks) > 0 {\n\t\toutput.Default.Fprintf(out, \"Starting %s hooks for artifact %q...\\n\", phase, r.imageName)\n\t}\n\tenv := r.getEnv()\n\tfor i, h := range hooks {\n\t\tif h.HostHook != nil {\n\t\t\thook := hostHook{*h.HostHook, env}\n\t\t\tif err := hook.run(ctx, nil, out); err != nil && !errors.Is(err, &Skip{}) {\n\t\t\t\treturn fmt.Errorf(\"failed to execute host %s hook %d for artifact %q: %w\", phase, i+1, r.imageName, err)\n\t\t\t}\n\t\t} else if h.ContainerHook != nil {\n\t\t\thook := containerHook{\n\t\t\t\tcfg:        *h.ContainerHook,\n\t\t\t\tcli:        r.cli,\n\t\t\t\tselector:   runningImageSelector(r.imageRef),\n\t\t\t\tnamespaces: r.namespaces,\n\t\t\t\tformatter:  r.formatter,\n\t\t\t}\n\t\t\tif err := hook.run(ctx, out); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to execute container %s hook %d for artifact %q: %w\", phase, i+1, r.imageName, err)\n\t\t\t}\n\t\t}\n\t}\n\tif len(hooks) > 0 {\n\t\toutput.Default.Fprintf(out, \"Completed %s hooks for artifact %q\\n\", phase, r.imageName)\n\t}\n\treturn nil","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/hooks/sync.go#L68-L104","documentation":"During sync (or dev) pre/post phases, skaffold runs each host hook defined for an artifact. If a host (local shell) hook fails — and the failure is not a deliberate Skip — run wraps the original error with the phase, 1-based hook index, artifact image name, and underlying error, then aborts the sync.","triggerScenarios":"A hostHook command in skaffold.yaml (e.g. `before-hooks`/`after-hooks` under sync) exits non-zero, times out, or the executable isn't found while RunPreHooks/RunPostHooks iterate hooks for artifact r.imageName.","commonSituations":"Hook script missing execute bit or not on PATH; command exits non-zero due to a failing migration or script bug; shell interpreter missing in minimal environments; intentional failure during tests.","solutions":["Read the wrapped %w error in the message — it names the failing command and exit reason; fix that command","Test the hook command manually with the same working directory skaffold uses (the build workspace)","Make the hook executable (chmod +x) or use an explicit interpreter prefix (sh -c ...)","If the hook may legitimately fail, handle the Skip sentinel or make the script exit 0 with a warning"],"exampleFix":"// before (skaffold.yaml)\nsync:\n  hooks:\n    before:\n      - host:\n          command: [\"./scripts/migrate\"]\n// after\nsync:\n  hooks:\n    before:\n      - host:\n          command: [\"sh\", \"-c\", \"./scripts/migrate || echo 'migration skipped' >&2\"]","handlingStrategy":"try-catch","validationCode":"// pre-check host hooks before enabling them in sync:\nfor _, cmd := range hookCmds {\n    if err := exec.Command(\"sh\", \"-c\", \"command -v \"+cmd[0]).Run(); err != nil {\n        return fmt.Errorf(\"hook command %q not available\", cmd[0])\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := syncRunner.RunPreHooks(ctx, out); err != nil {\n    var skip *hooks.Skip\n    if !errors.As(err, &skip) {\n        log.Printf(\"host hook failed: %v\", err) // wrapped msg names phase, hook index, artifact\n    }\n}","preventionTips":["Test each host hook manually from the build workspace before adding it to config","Use sh -c with explicit interpreter paths; add scripts to the repo with +x","Keep host hooks idempotent and fast so failures are easy to retry"],"tags":["sync","hooks","shell","skaffold"],"backgroundTag":"hook-command-failed","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"}