{"record":{"id":"4c9b32581def6e8b","repo":"GoogleContainerTools/skaffold","slug":"getting-render-output-path-w","errorCode":null,"errorMessage":"getting render output path: %w","messagePattern":"getting render output path: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/runner/new.go","lineNumber":79,"sourceCode":"\tsourceDependencies := graph.NewSourceDependenciesCache(runCtx, store, g)\n\n\tisLocalImage := func(imageName string) (bool, error) {\n\t\treturn isImageLocal(runCtx, imageName)\n\t}\n\n\t// Always add skaffold-specific labels, except during `skaffold render`\n\tlabeller := label.NewLabeller(runCtx.AddSkaffoldLabels(), runCtx.CustomLabels(), runCtx.GetRunID())\n\ttester, err := getTester(ctx, runCtx, isLocalImage)\n\tif err != nil {\n\t\tendTrace(instrumentation.TraceEndError(err))\n\t\treturn nil, fmt.Errorf(\"creating tester: %w\", err)\n\t}\n\n\tvar deployer deploy.Deployer\n\n\thydrationDir, err := util.GetHydrationDir(runCtx.Opts, runCtx.WorkingDir, true, isKptRendererOrDeployerUsed(runCtx.Pipelines))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting render output path: %w\", err)\n\t}\n\n\trenderer, err := GetRenderer(ctx, runCtx, hydrationDir, labeller.Labels(), runCtx.UsingLegacyHelmDeploy())\n\tif err != nil {\n\t\tendTrace(instrumentation.TraceEndError(err))\n\t\treturn nil, fmt.Errorf(\"creating renderer: %w\", err)\n\t}\n\n\tdeployer, err = GetDeployer(ctx, runCtx, labeller, hydrationDir, runCtx.UsingLegacyHelmDeploy())\n\tif err != nil {\n\t\tendTrace(instrumentation.TraceEndError(err))\n\t\treturn nil, fmt.Errorf(\"creating deployer: %w\", err)\n\t}\n\trOpts := platform.ResolverOpts{\n\t\tKubeContext:               runCtx.KubeContext,\n\t\tCliPlatformsSelection:     runCtx.Opts.Platforms,\n\t\tCheckClusterNodePlatforms: runCtx.CheckClusterNodePlatforms(),\n\t\tDisableMultiPlatformBuild: runCtx.DisableMultiPlatformBuild(),","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/runner/new.go#L61-L97","documentation":"Before creating the renderer, `NewForConfig` resolves the hydration directory (where rendered k8s manifests are written, default `.kpt-pipeline`) via `util.GetHydrationDir`. This wraps failures to compute or create that directory — filesystem path errors or mkdir permission failures.","triggerScenarios":"Using a kpt renderer/deployer while `filepath.Abs(opts.HydrationDir)` fails, or `os.MkdirAll(hydrationDir)` fails because the parent directory is read-only, the path exists as a file, or the disk is full.","commonSituations":"Running `skaffold dev`/`render` with `--hydration-dir` inside a read-only mount; `--hydration-dir` colliding with an existing regular file; restricted CI container filesystems.","solutions":["Ensure the `--hydration-dir` path's parent is writable (`ls -ld`, check permissions).","Confirm the hydration dir path is not an existing regular file; remove or rename it.","If not using kpt, no hydration dir is needed — check why a kpt renderer/deployer was selected (skaffold.yaml renderer/deployer config).","In CI, use `--assume-yes=true` to skip the interactive non-empty-dir prompt that can otherwise hang or exit."],"exampleFix":"// CI command before\nskaffold render --hydration-dir /ro-mount/.kpt-pipeline\n// after\nskaffold render --hydration-dir /tmp/.kpt-pipeline --assume-yes=true","handlingStrategy":"validation","validationCode":"func hydrationDirReady(dir string) error {\n  st, err := os.Stat(dir)\n  if err == nil && !st.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", dir)\n  }\n  return os.MkdirAll(dir, 0o755)\n}","typeGuard":null,"tryCatchPattern":"runner, err := runner.NewForConfig(runCtx)\nif err != nil {\n  if strings.Contains(err.Error(), \"getting render output path\") {\n    return fmt.Errorf(\"hydration dir unusable (permissions? file conflict?): %w\", err)\n  }\n  return err\n}","preventionTips":["Point --hydration-dir at a writable location (e.g. /tmp in containers).","Never let the hydration dir path collide with a regular file.","Use --assume-yes=true in non-interactive CI to skip prompts.","Check disk space and mount permissions in CI images."],"tags":["filesystem","kpt","hydration-dir","permissions"],"backgroundTag":"hydration-dir-unwritable","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"}