skip to content

How do you make plugin validation problems fail the build instead of just warning?

level: middleimportance: must knowfreq 50%

answer

  1. failOnWarning = true
  2. enableStricterValidation
  3. tasks.withType<ValidatePlugins>
  4. escalate warning to error
  5. hard CI gate

basics

~10 s

Configure the ValidatePlugins task with failOnWarning = true. Then any TypeValidationProblem becomes a build failure rather than a warning, so missing annotations break the build.

solid answer

~40 s

By default `validatePlugins` reports each `TypeValidationProblem` as a warning and the build stays green, which is easy to ignore. To enforce a clean plugin you set `failOnWarning = true` on the `ValidatePlugins` task. Then every validation problem — a property with no input/output annotation, a conflicting annotation, a missing `@PathSensitive` — is escalated to an error and fails the build. Because the task already runs under `check`, this turns plugin validation into a hard CI gate. You configure it by type so it applies to all instances: ```kotlin tasks.withType<ValidatePlugins>().configureEach { failOnWarning = true enableStricterValidation = true } ``` `enableStricterValidation` additionally enforces stronger rules (e.g. requiring `@PathSensitive` on file inputs). This is the standard hardening for any plugin you intend to publish.

code

kotlin · 6 lines
kotlin
import org.gradle.plugin.devel.tasks.ValidatePlugins

tasks.withType<ValidatePlugins>().configureEach {
    failOnWarning = true
    enableStricterValidation = true
}

go deeper

for a junior

Know that failOnWarning = true turns validation warnings into build failures.

for a middle

Configure it correctly via tasks.withType<ValidatePlugins>().configureEach and explain why it matters for published plugins.

for a senior

Add enableStricterValidation, tie it to up-to-date/cache correctness, and make it a CI gate.

for a principal

Mandate fail-on-warning + stricter validation as org policy for all internal plugins and enforce in shared build conventions.

## The default is permissive Out of the box, `validatePlugins` is *advisory*: each problem is logged as a warning and the build still succeeds. In a real plugin project that is dangerous — a missing `@OutputFile` silently breaks up-to-date checking for everyone who consumes the plugin, and nobody notices because the build was green. ## failOnWarning The `org.gradle.plugin.devel.tasks.ValidatePlugins` task exposes a `failOnWarning` property. Setting it to `true` escalates every `TypeValidationProblem` from warning to error, so the task — and therefore `check` — fails when any problem exists. ```kotlin tasks.withType<ValidatePlugins>().configureEach { failOnWarning = true } ``` Configuring `withType(...).configureEach { }` rather than a single named task is the robust approach: it covers every `ValidatePlugins` instance (there can be more than one in multi-source-set setups) and uses lazy configuration so the task isn't realized unnecessarily. ## enableStricterValidation The same task type also exposes `enableStricterValidation`. When `true`, Gradle applies the stricter rule set used for *Gradle's own* plugins — for instance it requires `@PathSensitive` (or an explicit `@PathSensitivity`) on file/dir inputs, and is more demanding about normalization and missing annotations. Combined with `failOnWarning`, this gives you a rigorous gate. ## Why this is the published-plugin standard - Up-to-date checking and the build cache are only **correct** if every input/output is annotated. A warning you ignore becomes a correctness bug in your consumers' builds. - Failing the build forces the author to fix the metadata before shipping. - It is cheap: validation is static analysis, runs in milliseconds, and is cacheable. ## Relationship to validating external plugins For plugins you did not author (already built jars), the validation can be applied to external artifacts (the `validateExternalPlugins`/`ValidateExternalPlugins` machinery), where the same fail-on-problem philosophy lets you gate third-party plugins in CI.

  • What extra rules does enableStricterValidation add?
    It applies the stricter rule set Gradle uses for its own plugins — e.g. requiring @PathSensitive/normalization on file inputs and being stricter about missing annotations — on top of failing on any warning.
  • Why configure with withType().configureEach instead of a named task?
    There can be multiple ValidatePlugins instances, and configureEach is lazy — it applies to all of them without eagerly realizing the tasks.

saying these in an interview costs you the question

  • Saying you must write a custom doFirst to throw — there is a first-class failOnWarning property.
  • Confusing failOnWarning (escalate to error) with disabling the task.

context