# google/error-prone: Catching Java Mistakes at Compile Time

> Error Prone is a static analysis tool for Java that reports common programming mistakes as compiler errors. This article covers what it catches, how it hooks into javac, how to install it with Maven or Bazel, and where it will not help you.

**google/error-prone** — Catch common Java mistakes as compile-time errors

- Repository: https://github.com/google/error-prone
- Website: https://errorprone.info
- Stars: 7,243 · Forks: 825
- Language: Java
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/google-error-prone

## The bug class Error Prone is built for

Java's type system is strong, but it does not stop every mistake that compiles cleanly. The README opens with a small program that builds a Set<Short>, then calls s.remove(i - 1) inside a loop. The argument is an int, the collection holds Short values, so the removal never matches anything and the loop silently keeps every element. Nothing about that code is unusual or exotic. It is the kind of slip that survives code review because the line looks right.

Error Prone's answer is to move the detection into the compiler. The README shows the resulting diagnostic: error: [CollectionIncompatibleType] Argument 'i - 1' should not be passed to this method; its type int is not compatible with its collection's type argument Short, followed by the source line and a link to https://errorprone.info/bugpattern/CollectionIncompatibleType. The check is named, the offending expression is named, and the build fails. That naming convention matters in practice: the bracketed identifier is what you look up when you need to understand or suppress a finding.

The audience is Java teams already using javac, not polyglot shops looking for one scanner across many languages. If your build compiles Java with a standard toolchain, Error Prone can sit inside that step.

## How Error Prone hooks into javac

Error Prone is a compiler plugin rather than a standalone program that parses source separately. It attaches to javac and runs its checks during compilation, which is why the README can describe findings as compile-time errors and why the output above is formatted like a compiler diagnostic rather than a report from a separate tool. The practical consequence is that Error Prone sees resolved types, not just tokens. Knowing that i - 1 is an int and that the receiver is a Set<Short> is what makes CollectionIncompatibleType possible at all.

The repository layout reflects that architecture. There is a core/ directory, a check_api/ directory, and separate annotation/ and annotations/ directories, plus test_helpers/ and refaster/. The presence of a dedicated check API means the bug patterns are written against an internal interface rather than being hardcoded into the compiler integration, which is how a project accumulates many checks over time. The refaster/ directory is a separate piece of the same repository; the README does not describe it, so treat it as something to investigate on its own rather than as part of the basic setup.

The docs/ directory and docgen/ and docgen_processor/ entries suggest the per-check documentation pages are generated from the checks themselves. That is a reasonable guess from the layout, not a documented guarantee, but it explains why every diagnostic in the README carries a URL with the check name in the path.

## Installing Error Prone and reading your first finding

The README does not reproduce installation steps. It states that documentation lives at errorprone.info and that Error Prone works with Bazel, Maven, Ant, and Gradle, with details in the installation instructions at errorprone.info/docs/installation. Those pages are the source of truth for plugin coordinates and compiler arguments; the repository README alone is not enough to configure a build.

What the README does give is the shape of the first useful result. Take the ShortSet example, compile it with Error Prone enabled through your build tool, and you should see a diagnostic naming the check and pointing at the expression:

```
error: [CollectionIncompatibleType] Argument 'i - 1' should not be passed to this method;
its type int is not compatible with its collection's type argument Short
      s.remove(i - 1);
              ^
    (see https://errorprone.info/bugpattern/CollectionIncompatibleType)
1 error
```

The first thing to do with that output is follow the URL. Each check has a documentation page keyed by the bracketed name, and that page is where you learn whether the finding is a real bug in your code or a pattern your team has decided to accept. If you decide to accept it, the same naming scheme is what you reference when suppressing the check, which is a build configuration decision rather than a code change you should make blindly.

A second step worth taking early: run Error Prone on a branch and count how many findings appear before you make it fail the build. The README presents Error Prone as producing errors, and the example output ends with 1 error, so a codebase that has never run it should expect a first pass that stops compilation.

## Where Error Prone is the wrong tool

Error Prone only knows what javac knows. Checks that depend on runtime behavior, configuration files, dependency versions or data flow across service boundaries are outside what a compiler plugin can see. The README's own example is a type mismatch, and that is the natural ceiling: if the mistake is expressible as a property of the compiled Java, it is fair game; if it is not, no amount of check writing will reach it.

There is also a build-coupling cost that the README does not discuss. Because Error Prone runs inside compilation, it runs wherever compilation runs: local incremental builds, IDE builds, CI, and any tool that invokes javac. A check that fires on a pattern your team considers acceptable will interrupt all of those, and the fix is a configuration change in each build path rather than a single ignore file. Teams that want findings to accumulate in a dashboard and be triaged later are looking at a different category of tool.

The third limitation is scope. The repository is Java, the topics listed are java and static-analysis, and the README names Bazel, Maven, Ant and Gradle as the supported build systems. Nothing in the README suggests Error Prone analyzes Kotlin, Scala, or any other JVM language, and nothing suggests it inspects compiled bytecode of dependencies rather than the sources being compiled.

## Error Prone compared with running a separate analyzer

The obvious alternative is a standalone static analysis tool that reads source or bytecode outside the build and writes a report. The difference in approach is not cosmetic. A separate analyzer can be run on demand, on a schedule, or on a subset of the codebase, and its findings do not stop a build. Error Prone makes the opposite trade: it removes the separate run entirely and makes the compiler the enforcement point.

That trade buys type information for free, since the compiler has already resolved every symbol, and it removes the problem of a report nobody reads. It costs flexibility. You cannot run Error Prone without compiling, and you cannot easily treat one check as advisory while another blocks the build without touching build configuration. A standalone analyzer typically has a severity model and a baseline file built for exactly that purpose.

Neither approach dominates. If your team's failure mode is ignoring a report, the compiler-as-enforcement-point model is the stronger fit. If your failure mode is a build that breaks for reasons unrelated to the change under review, a separate analyzer with triage is easier to live with. The README's framing, catching mistakes at compile-time, is an explicit statement of which side of that line the project chose.

## Maintenance, releases and licence

The repository is not archived, and the last push was on 2026-09-21, one day before this writing, so the project is being worked on now. Releases are frequent: v2.50.0 on 2026-06-10, v2.49.0 on 2026-04-07, and v2.48.0 on 2026-02-27, which is roughly a two-month cadence across the three most recent tags shown. For a compiler plugin, that cadence is the relevant upgrade signal, because a new Error Prone version usually means new checks, and new checks mean new build failures on code that previously compiled.

That is the upgrade cost in one sentence: bumping the version can turn a green build red without any change to your source. Plan for it the way you plan for a compiler upgrade, and keep the version pinned rather than floating. Pre-release snapshots are published to Sonatype's snapshot repository at https://central.sonatype.com/repository/maven-snapshots/, according to the README, which is useful if you need a fix before a tagged release but is not a place to build from for production.

The licence is Apache-2.0, and the repository carries COPYING and AUTHORS files consistent with that. Apache-2.0 is a permissive licence with an explicit patent grant and requires preservation of notices; if you redistribute Error Prone or a modified version, read COPYING rather than relying on a summary, and treat any question about your own obligations as one for your legal team rather than for this article.

## Conclusion

Adopt Error Prone if you have a Java codebase that compiles with javac through Maven, Gradle, Ant or Bazel, and you want type-aware bug patterns such as CollectionIncompatibleType to fail the build rather than sit in a report. Do not adopt it as a language-agnostic scanner or as a replacement for a security-focused analyzer; the repository is a Java compiler plugin, and the README names no other language. Before rolling it out, verify which JDK your build uses, because the installation instructions at errorprone.info are the only place the supported configurations are documented, and verify how your build tool's incremental compilation behaves once the compiler plugin is attached.

## FAQ

### What does Error Prone do?

It is a static analysis tool for Java that catches common programming mistakes at compile-time, according to the README. Findings are reported as compiler errors, for example the CollectionIncompatibleType diagnostic shown in the README.

### How do I install Error Prone?

The README does not list installation steps; it points to the documentation at errorprone.info and to the installation instructions at errorprone.info/docs/installation. Those pages cover the supported build systems: Bazel, Maven, Ant and Gradle.

### Which build tools does Error Prone work with?

The README states that Error Prone works with Bazel, Maven, Ant and Gradle. Installation details for each are in the documentation at errorprone.info rather than in the repository README.

### What does the bracketed name in an Error Prone error mean?

It is the name of the check that produced the finding. In the README example the diagnostic reads error: [CollectionIncompatibleType], and the message includes a link to https://errorprone.info/bugpattern/CollectionIncompatibleType.

## Sources

- [google/error-prone on GitHub](https://github.com/google/error-prone)
- [License: Apache-2.0](https://github.com/google/error-prone/blob/master/LICENSE)
- [Project website](https://errorprone.info)
- [README](https://github.com/google/error-prone/blob/master/README.md)
- [Releases](https://github.com/google/error-prone/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/google-error-prone
