{"record":{"id":"64953b42a693b886","repo":"GoogleContainerTools/skaffold","slug":"running-builder-pre-hooks-w","errorCode":null,"errorMessage":"running builder pre-hooks: %w","messagePattern":"running builder pre-hooks: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/runner/builder.go","lineNumber":93,"sourceCode":"\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown builder for config %+v\", p.Build)\n\t}\n}\n\ntype pipelineBuilderWithHooks struct {\n\tbuild.PipelineBuilder\n\thooksRunner hooks.Runner\n}\n\n// PreBuild executes any one-time setup required prior to starting any build on this builder,\n// followed by any Build pre-hooks set for the pipeline.\nfunc (b *pipelineBuilderWithHooks) PreBuild(ctx context.Context, out io.Writer) error {\n\tif err := b.PipelineBuilder.PreBuild(ctx, out); err != nil {\n\t\treturn err\n\t}\n\n\tif err := b.hooksRunner.RunPreHooks(ctx, out); err != nil {\n\t\treturn fmt.Errorf(\"running builder pre-hooks: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// PostBuild executes any one-time teardown required after all builds on this builder are complete,\n// followed by any Build post-hooks set for the pipeline.\nfunc (b *pipelineBuilderWithHooks) PostBuild(ctx context.Context, out io.Writer) error {\n\tif err := b.PipelineBuilder.PostBuild(ctx, out); err != nil {\n\t\treturn err\n\t}\n\n\tif err := b.hooksRunner.RunPostHooks(ctx, out); err != nil {\n\t\treturn fmt.Errorf(\"running builder post-hooks: %w\", err)\n\t}\n\n\treturn nil\n}","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/runner/builder.go#L75-L111","documentation":"pipelineBuilderWithHooks.PreBuild runs the underlying builder's PreBuild, then executes the user-configured build pre-hooks. If any pre-hook command fails, the error is wrapped as \"running builder pre-hooks: %w\" so the hook's own failure output is preserved in the chain.","triggerScenarios":"A `build.preHooks` (or lifecycle pre-build hooks) command defined in skaffold.yaml exits non-zero during a `skaffold build`/`dev`/`run` invocation.","commonSituations":"Pre-hook scripts that generate code or download dependencies failing due to missing tools (not on PATH), network failures, or non-portable shell commands on the developer's OS.","solutions":["Read the wrapped underlying error and fix the failing pre-hook command in skaffold.yaml","Run the hook command manually in your shell to reproduce and debug it","Ensure hook scripts are executable and available on PATH (chmod +x, correct shebang)"],"exampleFix":"// before (skaffold.yaml)\nbuild:\n  preHooks:\n    - exec: ./scripts/generate.sh   # not executable\n// after\nchmod +x ./scripts/generate.sh\n# and pin interpreter explicitly:\nbuild:\n  preHooks:\n    - exec: [\"bash\", \"./scripts/generate.sh\"]","handlingStrategy":"try-catch","validationCode":"// smoke-test pre-hooks before building\nsh(\"bash -n scripts/generate.sh && ./scripts/generate.sh --dry-run\")","typeGuard":null,"tryCatchPattern":"try {\n  await run('skaffold build')\n} catch (err) {\n  if (/running builder pre-hooks/.test(err.message)) {\n    // surface the wrapped hook error and rerun hooks manually for debugging\n    console.error('pre-hook failed:', err.cause ?? err.message)\n  }\n  throw err\n}","preventionTips":["Test hook scripts standalone before wiring them into skaffold.yaml","Use explicit interpreters (bash) and portable commands in hooks","Keep hooks idempotent and dependency-free or fail fast with clear messages"],"tags":["build","hooks","lifecycle"],"backgroundTag":"build-hook-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"}