{"record":{"id":"d4f7da929b9778d8","repo":"GoogleContainerTools/skaffold","slug":"parsing-dockerfile-w","errorCode":null,"errorMessage":"parsing dockerfile: %w","messagePattern":"parsing dockerfile: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/docker/parse.go","lineNumber":156,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif cpCmd != nil && len(cpCmd.srcs) > 0 {\n\t\t\t\tfor _, src := range cpCmd.srcs {\n\t\t\t\t\tcopied = append(copied, FromTo{From: src, To: cpCmd.dest, ToIsDir: cpCmd.destIsDir, StartLine: cpCmd.startLine, EndLine: cpCmd.endLine})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn copied, nil\n}\n\n// filterUnusedBuildArgs removes entries from the build arguments map that are not found in the dockerfile\nfunc filterUnusedBuildArgs(dockerFile io.Reader, buildArgs map[string]*string) (map[string]*string, error) {\n\tres, err := parser.Parse(dockerFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing dockerfile: %w\", err)\n\t}\n\tm := make(map[string]*string)\n\tfor _, n := range res.AST.Children {\n\t\tif strings.ToLower(n.Value) != command.Arg {\n\t\t\tcontinue\n\t\t}\n\t\tk := strings.SplitN(n.Next.Value, \"=\", 2)[0]\n\t\tif v, ok := buildArgs[k]; ok {\n\t\t\tm[k] = v\n\t\t}\n\t}\n\treturn m, nil\n}\n\nfunc expandBuildArgs(nodes []*parser.Node, buildArgs map[string]*string) error {\n\targs, err := util.EvaluateEnvTemplateMap(buildArgs)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to evaluate build args: %w\", err)","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/docker/parse.go#L138-L174","documentation":"filterUnusedBuildArgs parses the Dockerfile to discover which ARG names it declares, then drops build-arg entries the file never uses. If parser.Parse fails here, the error is wrapped WITHOUT a file path ('parsing dockerfile: %w'), which makes it slightly harder to attribute — it is still a raw Dockerfile syntax failure. This path is reached from evalBuildArgs during image build configuration.","triggerScenarios":"evalBuildArgs (or an anonymous caller) passes a dockerfile reader whose content parser.Parse rejects — same class of syntax problems as 320/321/324, but hit while pruning unused build args.","commonSituations":"The same broken Dockerfile that later fails the main parse; a programmatically generated Dockerfile string with a syntax bug; test fixtures or inline Dockerfile content that is invalid.","solutions":["Fix the Dockerfile syntax named in the inner error (lint with hadolint or 'docker build --check')","Because this message lacks the file path, search your pipeline for the dockerfile source being read at this point and validate it directly","If content is generated at runtime, print/dump it on failure and inspect the offending line","Run the parse path with a known-good minimal Dockerfile to confirm the problem is file content, not caller wiring"],"exampleFix":"// before\nFROM base as  \n// after\nFROM base AS build","handlingStrategy":"validation","validationCode":"func pruneArgsSafely(dockerFile io.Reader, buildArgs map[string]*string) (map[string]*string, error) {\n    content, err := io.ReadAll(dockerFile)\n    if err != nil { return nil, err }\n    if _, err := parser.Parse(bytes.NewReader(content)); err != nil {\n        return nil, fmt.Errorf(\"dockerfile content invalid before arg pruning: %w\", err)\n    }\n    return parser.Parse(bytes.NewReader(content)) // proceed\n}","typeGuard":"func dockerfileReaderIsValid(r io.Reader) bool {\n    b, err := io.ReadAll(r)\n    if err != nil { return false }\n    _, perr := parser.Parse(bytes.NewReader(b))\n    return perr == nil\n}","tryCatchPattern":"m, err := skaffoldPruneArgs(r, buildArgs)\nif err != nil && strings.Contains(err.Error(), \"parsing dockerfile:\") {\n    return fmt.Errorf(\"inline/generated dockerfile content invalid (no path in message): %w\", err)\n}","preventionTips":["Validate generated Dockerfile strings with parser.Parse before passing them in","Since this error message has no file path, log the dockerfile content at debug level around this call","Run hadolint on the source file feeding this reader","Keep test fixtures syntactically valid Dockerfiles"],"tags":["dockerfile","parsing","build-args"],"backgroundTag":"dockerfile-parse-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"}