{"record":{"id":"571f8279ec32a9dc","repo":"GoogleContainerTools/jib","slug":"src-is-not-a-parent-of-path","errorCode":null,"errorMessage":"${src} is not a parent of ${path}","messagePattern":"(.+?) is not a parent of (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"jib-cli/src/main/java/com/google/cloud/tools/jib/cli/buildfile/Layers.java","lineNumber":151,"sourceCode":"                          filePropertiesStack.getOwnership());\n\n              Set<Path> addedDirectories = new HashSet<>();\n              for (Path path : filtered) {\n                if (!Files.isDirectory(path) && !Files.isRegularFile(path)) {\n                  throw new UnsupportedOperationException(\n                      \"Cannot create FileLayers from non-file, non-directory: \" + src.toString());\n                }\n\n                if (Files.isDirectory(path)) {\n                  addedDirectories.add(path);\n                  layerBuiler.addEntry(\n                      newEntry.apply(path, filePropertiesStack.getDirectoryPermissions()));\n                } else if (Files.isRegularFile(path)) {\n                  if (!path.startsWith(src)) {\n                    // if we end up in a situation where the file added is somehow outside of the\n                    // tree then we do not know how to properly handle it at the moment. It could\n                    // be from a link scenario that we do not understand.\n                    throw new IllegalStateException(\n                        src.toString() + \" is not a parent of \" + path.toString());\n                  }\n                  Path parent = Verify.verifyNotNull(path.getParent());\n                  while (true) {\n                    if (addedDirectories.contains(parent)) {\n                      break;\n                    }\n                    layerBuiler.addEntry(\n                        newEntry.apply(parent, filePropertiesStack.getDirectoryPermissions()));\n                    addedDirectories.add(parent);\n                    if (parent.equals(src)) {\n                      break;\n                    }\n                    parent = Verify.verifyNotNull(parent.getParent());\n                  }\n                  layerBuiler.addEntry(\n                      newEntry.apply(path, filePropertiesStack.getFilePermissions()));\n                }","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-cli/src/main/java/com/google/cloud/tools/jib/cli/buildfile/Layers.java#L133-L169","documentation":"While adding regular-file entries from a directory walk, Layers.toLayers asserts every file is under the resolved src tree; otherwise it cannot compute parent directories consistently. This usually arises from filesystem link scenarios Jib does not model. When a walked path does not start with src, it throws IllegalStateException '<src> is not a parent of <path>'.","triggerScenarios":"Directory copy where the walked tree contains symlinks pointing outside the src directory (or hard-to-resolve link layouts) such that a discovered regular file path is not a descendant of the resolved src.","commonSituations":"Symlinked directories pointing outside the build root (e.g. node_modules symlinks to a global store), symlink chains escaping the copied tree.","solutions":["Replace out-of-tree symlinks with real copies of the target content before building.","Remove symlinks in the copied directory that escape the src tree.","Restructure the source layout so all referenced content lives under the src directory.","Split the copy into multiple specs copying the real directories directly."],"exampleFix":"// before\nbuild/ -> /somewhere/else  (symlink escaping src)\n// after\ncp -rL /somewhere/else build/  // materialize real files inside src","handlingStrategy":"validation","validationCode":"try (var walk = Files.walk(srcDir)) {\n  var escaping = walk.filter(Files::isRegularFile)\n      .filter(p -> !p.toRealPath().startsWith(srcDir.toRealPath()))\n      .toList();\n  if (!escaping.isEmpty()) throw new IllegalStateException(\"Symlinks escape src tree: \" + escaping);\n}","typeGuard":null,"tryCatchPattern":"try {\n  jibBuild();\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"is not a parent of\")) {\n    log.error(\"Copy tree contains symlinks pointing outside the source directory\");\n  } else throw e;\n}","preventionTips":["Avoid symlinks that escape the copied directory (node_modules global stores, etc.)","Use cp -rL to materialize real files before building","Keep copied trees self-contained under the src path"],"tags":["symlink","filesystem","buildfile"],"backgroundTag":"invalid-argument-value","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}