{"record":{"id":"a25062a15774297e","repo":"gradle/gradle","slug":"plugin-validation-finished-with-warnings","errorCode":null,"errorMessage":"Plugin validation finished with warnings:{}{}","messagePattern":"Plugin validation finished with warnings:(.+?)(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platforms/extensibility/plugin-development/src/main/java/org/gradle/plugin/devel/tasks/ValidatePlugins.java","lineNumber":192,"sourceCode":"        List<? extends ProblemInternal> warnings = parsedProblems.getWarnings();\n        List<? extends ProblemInternal> errors = parsedProblems.getErrors();\n\n        if (errors.isEmpty() && warnings.isEmpty()) {\n            getLogger().info(\"Plugin validation finished without warnings.\");\n        } else if (getFailOnWarning().get() || !errors.isEmpty()) {\n            if (getIgnoreFailures().get()) {\n                getLogger().warn(\"Plugin validation finished with errors. {}{}{}\",\n                    annotateTaskPropertiesDoc(),\n                    System.lineSeparator(),\n                    renderProblems(warnings, errors));\n            } else {\n                ProblemReporter reporter = getServices().get(ProblemsInternal.class).getReporter();\n                List<ProblemInternal> reportedProblems = WorkValidationUtils.deduplicateAndTruncate(Stream.concat(warnings.stream(), errors.stream()).collect(toImmutableList()));\n                WorkValidationException exception = WorkValidationException.withSummaryForPlugin(reportedProblems.size(), List.of(annotateTaskPropertiesDoc()));\n                throw reporter.throwing(exception, reportedProblems);\n            }\n        } else {\n            getLogger().warn(\"Plugin validation finished with warnings:{}{}\",\n                System.lineSeparator(),\n                renderProblems(warnings, errors));\n        }\n    }\n\n    private static String renderProblems(List<? extends ProblemInternal> warnings, List<? extends ProblemInternal> errors) {\n        List<ProblemInternal> all = Stream.concat(warnings.stream(), errors.stream()).collect(toImmutableList());\n        StringWriter writer = new StringWriter();\n        ProblemWriter.simple().write(all, writer);\n        return writer.toString();\n    }\n\n    private String annotateTaskPropertiesDoc() {\n        return getDocumentationRegistry().getDocumentationRecommendationFor(\"on how to annotate task properties\", \"incremental_build\", \"sec:task_input_output_annotations\");\n    }\n\n    /**\n     * The classes to validate.","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/extensibility/plugin-development/src/main/java/org/gradle/plugin/devel/tasks/ValidatePlugins.java#L174-L210","documentation":"The validatePlugins task runs java-gradle-plugin validation and splits results into warnings and errors. With only warnings present (or with errors when ignoreFailures is true), it logs this summary followed by the rendered problem list instead of failing the build. The rendered problems name each concrete issue, such as descriptor mismatches or task properties missing validation annotations.","triggerScenarios":"Running validatePlugins (or build, which wires it in) on a plugin project where validation produced warnings, e.g. the descriptor warnings from JavaGradlePluginPlugin (missing/invalid descriptors) or custom task properties lacking @Input/@Output annotations. With getIgnoreFailures() = true even errors only produce this warning.","commonSituations":"Plugin projects with incomplete gradlePlugin declarations; custom tasks without proper property annotations; teams temporarily setting validatePlugins.ignoreFailures = true.","solutions":["Read the rendered problems directly below the summary line: they identify each offending plugin, task, and property.","Fix each item: correct descriptors and annotate custom task properties with @Input, @Output, @Internal etc. per the linked task properties documentation.","Remove validatePlugins.ignoreFailures = true once fixed so real errors fail the build again.","Run ./gradlew validatePlugins alone for fast iteration while fixing."],"exampleFix":"// before: task property without validation annotation -> warning\nabstract class MyTask extends DefaultTask {\n    String fileName\n}\n\n// after\nabstract class MyTask extends DefaultTask {\n    @Input String fileName\n}","handlingStrategy":"validation","validationCode":"tasks.named('validatePlugins') {\n    ignoreFailures = false // make validation problems fail CI instead of warn\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run ./gradlew validatePlugins in CI with ignoreFailures left at false.","Annotate every custom task property with @Input/@Output/@Internal as appropriate.","Treat each rendered warning as a to-do item before publishing a plugin."],"tags":["gradle","plugin-development","validation","task-properties"],"backgroundTag":"plugin-validation-warnings","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}