{"record":{"id":"9a22656a43e5f365","repo":"goreleaser/goreleaser","slug":"pre-hook-failed-w","errorCode":null,"errorMessage":"pre hook failed: %w","messagePattern":"pre hook failed: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pipe/docker/v2/docker.go","lineNumber":247,"sourceCode":"\t}\n\n\tlog.WithField(\"id\", d.ID).\n\t\tWithField(\"images\", strings.Join(da.images, \"\\n\")).\n\t\tInfo(\"creating images\")\n\n\twd, err := makeContext(d, contextArtifacts(ctx, d), da.dockerfile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer os.RemoveAll(wd)\n\n\thookFields := tmpl.Fields{\n\t\tkeyImages:     da.images,\n\t\tkeyDockerfile: da.dockerfile,\n\t\tkeyContextDir: wd,\n\t}\n\tif err := runHook(ctx, hookFields, d.Hooks.Pre); err != nil {\n\t\treturn fmt.Errorf(\"pre hook failed: %w\", err)\n\t}\n\n\tdigest, err := doBuild(ctx, d, wd, da.args)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\thookFields[keyDigest] = digest\n\tif err := runHook(ctx, hookFields, d.Hooks.Post); err != nil {\n\t\treturn fmt.Errorf(\"post hook failed: %w\", err)\n\t}\n\n\tlog.WithField(\"id\", d.ID).\n\t\tWithField(\"images\", strings.Join(da.images, \"\\n\")).\n\t\tWithField(\"digest\", digest).\n\t\tInfo(\"created images\")\n\n\tfor _, img := range da.images {","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/goreleaser/goreleaser/blob/f5edd7395693c0c6b501dc722d445d2e86af854d/internal/pipe/docker/v2/docker.go#L229-L265","documentation":"The dockers_v2 pipe runs user-defined pre-build hooks (shell commands) before `docker buildx build`. This error wraps any failure returned by runHook for the `hooks.pre` list, aborting the image build. It indicates a pre hook command exited non-zero or could not run.","triggerScenarios":"A `dockers_v2.hooks.pre` entry in .goreleaser.yaml returns a non-zero exit code, references a binary not on PATH, or its own template fails, during the docker build image step.","commonSituations":"Hook script missing execute permission, depending on tools only present locally but not in CI, using template fields (images/dockerfile/context dir) incorrectly, or a linter/formatter hook failing on generated files.","solutions":["Run the failing hook command manually with the same working directory to see its real error output.","Fix or remove the offending `hooks.pre` entry in .goreleaser.yaml.","Ensure any binaries/scripts the hook calls are installed and on PATH in the CI environment.","Check the hook's templates ({{ .Images }}, {{ .Dockerfile }}, {{ .ContextDir }}) resolve correctly."],"exampleFix":"// before (.goreleaser.yaml)\ndockers_v2:\n  - hooks:\n      pre:\n        - ./scripts/validate.sh\n// after (ensure executable or use sh)\ndockers_v2:\n  - hooks:\n      pre:\n        - sh ./scripts/validate.sh","handlingStrategy":"validation","validationCode":"// shell: pre-flight check that hook commands exist before running goreleaser\nfor cmd in $(yq '.dockers_v2[].hooks.pre[]' .goreleaser.yaml); do\n  command -v \"$(echo \"$cmd\" | awk '{print $1}')\" >/dev/null || { echo \"missing hook binary: $cmd\"; exit 1; }\ndone","typeGuard":null,"tryCatchPattern":"err := goreleaserRelease(ctx)\nif err != nil && strings.Contains(err.Error(), \"pre hook failed\") {\n    // surface the underlying hook output already logged by runHook\n    return fmt.Errorf(\"docker pre hook failed; check hook command and PATH: %w\", err)\n}","preventionTips":["Keep pre hooks simple and dependency-free; install dependencies in an earlier CI step","Use `sh -c` style entries so scripts don't need the execute bit","Smoke-test hooks locally with the same working directory goreleaser uses","Verify every binary a hook calls is on PATH in the CI image"],"tags":["goreleaser","docker","hooks","shell"],"backgroundTag":"build-hook-failed","analyzedSha":"f5edd7395693c0c6b501dc722d445d2e86af854d","analyzedAt":"2026-09-05T09:57:18.807Z","contentChangedAt":"2026-09-05T09:57:18.807Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}