{"record":{"id":"125257ba21da092d","repo":"apache/kafka","slug":"failed-to-check-internal-api-usage","errorCode":null,"errorMessage":"Failed to check internal API usage: {}","messagePattern":"Failed to check internal API usage: (.+?)","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaInternalApiCheckerTask.java","lineNumber":120,"sourceCode":"    private void handleNoKafkaDependency() {\n        String msg = \"No org.apache.kafka:* dependencies found on the configured \"\n                + \"kafkaDependencyJars. The checker cannot derive an API surface and would \"\n                + \"produce a meaningless '0 violations' report — likely a classpath or \"\n                + \"configuration issue.\";\n        if (failOnNoKafkaDependency.get()) {\n            throw new GradleException(msg);\n        }\n        getLogger().warn(\"{} Skipping internal API check. \"\n                + \"Set kafkaInternalApiChecker.failOnNoKafkaDependency = true to make this fatal.\", msg);\n    }\n\n    private void runCheck(List<File> kafkaJars, List<File> classRoots) {\n        try {\n            getLogger().info(\"Scanning {} class file root(s) for internal API usage\", classRoots.size());\n            CheckResult result = new PublicApiChecker(kafkaJars).checkBytecode(classRoots);\n            reportResults(result);\n        } catch (IOException e) {\n            throw new GradleException(\"Failed to check internal API usage: \" + e.getMessage(), e);\n        }\n    }\n\n    private void reportResults(CheckResult result) throws IOException {\n        List<PublicApiViolation> violations = result.violations();\n        List<PublicApiViolation> suppressions = result.suppressions();\n\n        ViolationReporter reporter = new ViolationReporter();\n        File report = reportFile.get().getAsFile();\n        reporter.writeTextReport(violations, suppressions, report);\n        reporter.printToConsole(violations, suppressions);\n\n        getLogger().info(\"Internal API usage check completed. Report written to: {}\", report.getAbsolutePath());\n\n        long unjustified = suppressions.stream().filter(PublicApiViolation::lacksReason).count();\n        if (unjustified > 0) {\n            getLogger().warn(\"{} suppression(s) carry no reason — KIP-1265 requires a justification on every @SuppressKafkaInternalApiUsage\", unjustified);\n        }","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/api-checker/gradle-plugins/src/main/java/org/apache/kafka/gradle/KafkaInternalApiCheckerTask.java#L102-L138","documentation":"Wrapped IOException thrown by KafkaInternalApiCheckerTask.runCheck when PublicApiChecker.checkBytecode fails to read class files or kafka jars. The original IOException is attached as the cause so the I/O failure reason is preserved. This indicates a filesystem/IO problem during the bytecode scan, not an API violation.","triggerScenarios":"new PublicApiChecker(kafkaJars).checkBytecode(classRoots) (line 116) throws IOException. Triggers when a configured class root or kafka jar is unreadable, deleted between configuration and execution, is a corrupt zip/jar, or the build runs with insufficient file permissions.","commonSituations":"Concurrent Gradle daemons or another process deleting build/ outputs mid-scan; stale/locked jar on Windows; corrupt downloaded dependency jar in the Gradle cache; classDirs pointing at a path that no longer exists after clean.","solutions":["Re-read the cause in the stack trace — getMessage() of the wrapped IOException names the offending file/path.","Run ./gradlew clean and rebuild so class roots and jars are regenerated consistently.","If a dependency jar is corrupt, clear the Gradle cache entry (~/.gradle/caches/modules-2/...) and re-resolve.","On Windows/CI, ensure no other process holds an exclusive lock on build outputs, and disable parallel daemons if files are being deleted mid-build."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight: ensure all configured roots/jars are readable\nList<File> inputs = new ArrayList<>(kafkaDependencyJars.getFiles());\ninputs.addAll(PublicApiChecker.collectExistingRoots(classDirs.get().getFiles()));\nfor (File f : inputs) {\n  if (!f.exists() || !f.canRead()) throw new IllegalStateException(\"Unreadable input: \" + f);\n}","typeGuard":null,"tryCatchPattern":"try { checkInternalApiUsage() } catch (GradleException e) { if (e.cause instanceof IOException) { logger.error('I/O during scan: ' + e.cause.message); /* clean + retry once */ } else throw e }","preventionTips":["Run ./gradlew clean before the check on CI to avoid mid-run file deletion.","Avoid parallel daemons deleting shared build outputs.","Periodically purge corrupt jars from the Gradle cache."],"tags":["gradle","api-checker","io","filesystem"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}