{"id":"a92f5afc04e2fbd9","repo":"spring-projects/spring-boot","slug":"failed-to-get-mode-from-filecopydetails","errorCode":null,"errorMessage":"Failed to get mode from FileCopyDetails","messagePattern":"Failed to get mode from FileCopyDetails","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java","lineNumber":485,"sourceCode":"\t\t\treturn (BootZipCopyAction.this.dirMode != null) ? BootZipCopyAction.this.dirMode : getPermissions(details);\n\t\t}\n\n\t\tprivate int getFileMode(FileCopyDetails details) {\n\t\t\treturn (BootZipCopyAction.this.fileMode != null) ? BootZipCopyAction.this.fileMode\n\t\t\t\t\t: getPermissions(details);\n\t\t}\n\n\t\tprivate int getPermissions(FileCopyDetails details) {\n\t\t\treturn (GradleVersion.current().compareTo(GradleVersion.version(\"8.3\")) >= 0)\n\t\t\t\t\t? details.getPermissions().toUnixNumeric() : getMode(details);\n\t\t}\n\n\t\tprivate int getMode(FileCopyDetails details) {\n\t\t\ttry {\n\t\t\t\treturn (int) details.getClass().getMethod(\"getMode\").invoke(details);\n\t\t\t}\n\t\t\tcatch (Exception ex) {\n\t\t\t\tthrow new RuntimeException(\"Failed to get mode from FileCopyDetails\", ex);\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Callback interface used to customize a {@link ZipArchiveEntry}.\n\t */\n\t@FunctionalInterface\n\tprivate interface ZipEntryCustomizer {\n\n\t\tZipEntryCustomizer NONE = (entry) -> {\n\t\t};\n\n\t\t/**\n\t\t * Customize the entry.\n\t\t * @param entry the entry to customize\n\t\t * @throws IOException on IO error","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/spring-projects/spring-boot/blob/5b2dbdbb8be64415eb6552f81ff7c449c8d251e6/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java#L467-L503","documentation":"Thrown by BootZipCopyAction.Processor.getMode() when reflective invocation of FileCopyDetails.getMode() fails. This fallback is selected only on Gradle < 8.3; on 8.3+ details.getPermissions().toUnixNumeric() is used. With the plugin's 8.14 floor this branch is unreachable in normal operation.","triggerScenarios":"getPermissions(details) routes to getMode(details) when GradleVersion.current() < 8.3; details.getClass().getMethod('getMode').invoke(details) throws, wrapped as RuntimeException at line 485.","commonSituations":"Unsupported old Gradle; a custom FileCopyDetails implementation lacking getMode; module restrictions blocking reflection.","solutions":["Upgrade Gradle to 8.14 or later so the modern getPermissions() path is used.","Ensure inputs are produced by standard Gradle copy sources (not custom FileCopyDetails).","Verify the JVM is not applying restrictive module access flags to Gradle internals."],"exampleFix":"// gradle/wrapper/gradle-wrapper.properties\n// before:\n//   distributionUrl=...gradle-8.2-bin.zip\n// after:\n//   distributionUrl=...gradle-8.14-bin.zip\n","handlingStrategy":"validation","validationCode":"import org.gradle.util.GradleVersion\nrequire(GradleVersion.current() >= GradleVersion.version(\"8.3\")) {\n    \"FileCopyDetails.getPermissions() requires Gradle 8.3+ (use 8.14+)\"\n}\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use Gradle 8.14+ so the modern getPermissions() path is taken.","Avoid injecting custom FileCopyDetails implementations into the archive copy stream."],"tags":["gradle","version-compat","reflection","file-permissions","boot-archive"],"analyzedSha":"5b2dbdbb8be64415eb6552f81ff7c449c8d251e6","analyzedAt":"2026-08-04T18:53:14.967Z","schemaVersion":2}