{"record":{"id":"c7f83164c3baf711","repo":"elastic/elasticsearch","slug":"could-not-add-details-to-tar-file-tarfile","errorCode":null,"errorMessage":"could not add [${details}] to tar file [${tarFile}]","messagePattern":"could not add \\[(.+?)\\] to tar file \\[(.+?)\\]","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTar.java","lineNumber":186,"sourceCode":"                }\n            }\n\n            private void visitFile(final FileCopyDetailsInternal details) {\n                final TarArchiveEntry entry = new TarArchiveEntry(details.getRelativePath().getPathString());\n                entry.setModTime(getModTime(details));\n                entry.setMode(UnixStat.FILE_FLAG | details.getPermissions().toUnixNumeric());\n                entry.setSize(details.getSize());\n                try {\n                    tar.putArchiveEntry(entry);\n                    details.copyTo(tar);\n                    tar.closeArchiveEntry();\n                } catch (final IOException e) {\n                    handleProcessingException(details, e);\n                }\n            }\n\n            private void handleProcessingException(final FileCopyDetailsInternal details, final IOException e) {\n                throw new GradleException(\"could not add [\" + details + \"] to tar file [\" + tarFile + \"]\", e);\n            }\n\n        }\n\n        private long getModTime(final FileCopyDetails details) {\n            return isPreserveFileTimestamps ? details.getLastModified() : 0;\n        }\n\n    }\n\n}\n","sourceCodeStart":168,"sourceCodeEnd":198,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/SymbolicLinkPreservingTar.java#L168-L198","documentation":"Thrown by SymbolicLinkPreservingTarStreamAction.handleProcessingException when writing a single archive entry fails with IOException. It wraps the per-entry failure (file, directory, or symbolic-link) with both the offending FileCopyDetails and the target tar, making it possible to identify exactly which input could not be added.","triggerScenarios":"In visitFile/visitDirectory/visitSymbolicLink: tar.putArchiveEntry(entry), details.copyTo(tar), Files.readSymbolicLink(...), or tar.closeArchiveEntry() throws IOException; handleProcessingException rethrows as GradleException with the details + tarFile. Common low-level causes: a path exceeding 100 chars without LONGFILE_GNU (mitigated here by setLongFileMode(LONGFILE_GNU)), a symlink target that cannot be read, or a file that vanished during the copy.","commonSituations":"A source file is deleted/moved between Gradle's tree walk and the tar write; a symbolic link target is unreadable or broken; a file grows during copy so entry.setSize mismatches the bytes written; very long relative paths; reading a symlink requires permissions the build user lacks.","solutions":["Inspect the details object in the message to identify the exact source path, then check it exists and is readable.","For a broken symbolic link, fix or remove the symlink in the source tree.","Ensure the build user has read/traverse permissions on the offending path and its parents.","Avoid mutating the task's input tree while the build runs; if generated, ensure the generating task is a proper dependency.","If a file changes size mid-copy, snapshot/stage the inputs into a stable directory first."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate each input before the tar action processes it:\nimport java.nio.file.*;\nvoid checkReadable(File f) {\n    if (!Files.exists(f.toPath()))\n        throw new IllegalArgumentException(\"missing input: \" + f);\n    if (!Files.isReadable(f.toPath()))\n        throw new IllegalArgumentException(\"unreadable input: \" + f);\n}\n// For symlinks also check the target:\nif (Files.isSymbolicLink(f.toPath())) {\n    Path target = Files.readSymbolicLink(f.toPath());\n    // ensure target resolves / is accessible\n}","typeGuard":null,"tryCatchPattern":"try {\n    tar.putArchiveEntry(entry);\n    details.copyTo(tar);\n    tar.closeArchiveEntry();\n} catch (final IOException e) {\n    handleProcessingException(details, e); // throws GradleException with details + tarFile\n}","preventionTips":["Do not mutate the task's input tree while the build runs.","Fix or remove broken symlinks in source trees that feed the tar task.","Ensure the build user has read/traverse permission on all inputs.","Stage volatile inputs into a stable directory before archiving."],"tags":["gradle","tar","archive","io","symlink","packaging"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}