skip to content

Author Diagnostics: Problems API

Reporting build problems as structured, machine-readable diagnostics instead of log lines. Interviewers ask because it is how a plugin's errors reach the IDE and the build scan with location and advice attached.

on this pageshow

explore

questions

16

What is the Gradle Problems Report HTML, where is it written, and when does Gradle generate it?

level: juniorimportance: must knowfreq 45%

answer

  1. build/reports/problems/problems-report.html
  2. aggregates all reported problems + deprecations
  3. self-contained HTML
  4. clickable file:// link in console
  5. generated only when problems exist

basics

~10 s

It is an aggregated HTML file at build/reports/problems/problems-report.html that lists all problems and deprecations Gradle and plugins reported during the build. Gradle generates it automatically when problems exist.

solid answer

~40 s

The Problems Report is a single self-contained HTML file written to `build/reports/problems/problems-report.html` in the root project's build directory. It aggregates every problem reported through Gradle's Problems API during the build — deprecation warnings, configuration-cache issues, and any custom problems plugins emit — into one browsable page grouped by category. Gradle writes it automatically when at least one problem was reported, and prints a clickable `file://` link to it in the console near the end of the build. It exists so a noisy console full of warnings becomes a structured, navigable document: you open it in a browser, expand groups, and see each problem's details, location, and any documented solutions in one place rather than scrolling terminal output.

code

bash · 10 lines
bash
$ ./gradlew build
...
> Task :compileJava
[Incubating] Problems report is available at: file:///home/me/app/build/reports/problems/problems-report.html

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

# Open it:
$ open build/reports/problems/problems-report.html   # macOS
$ xdg-open build/reports/problems/problems-report.html # Linux

go deeper

for a junior

Know the path, that it aggregates problems/deprecations, and that a link prints in the console.

for a middle

Explain it is self-contained, generated only when problems exist, and that Gradle deprecations flow through the same Problems API into it.

for a senior

Tie it to the Problems API pipeline — reported Problems are aggregated and grouped by ProblemId for the report — and discuss its role in CI artifacts.

for a principal

Position it as the org-wide diagnostics surface: standardize uploading it as a CI artifact and using it to drive deprecation-burndown before major Gradle upgrades.

## What the Problems Report is Gradle's **Problems API** (stable since Gradle 8.6+, with the HTML report maturing through 8.x) gives plugins and Gradle internals a structured way to report issues — instead of just calling `logger.warn(...)`, code reports a *Problem* with an identity, severity, location, and solutions. All of those reported problems are then aggregated into a single **HTML report**. The report is written to: ``` <rootProject>/build/reports/problems/problems-report.html ``` It is a **self-contained** HTML file (styles and data inlined) so you can open it directly in a browser or attach it to a CI artifact without extra assets. ## When it is generated Gradle generates the report at the end of the build **whenever one or more problems were reported** during that build. Because Gradle's own deprecation warnings now flow through the Problems API, almost any build that emits a deprecation will produce the report. If no problems were reported, no report is written. ## How it surfaces in the console Near the end of the build, the console prints a line such as: ``` [Incubating] Problems report is available at: file:///path/to/build/reports/problems/problems-report.html ``` Many terminals render that `file://` URL as a clickable link. There is also a `--problems-report` view aspect: the link is what connects the terse console summary (e.g. "Deprecated Gradle features were used...") to the full structured detail. ## What it contains The page groups problems by their **ProblemId** hierarchy — a group label plus a specific id — so all problems of the same kind cluster together. For each problem you typically see: the human-readable label, severity (WARNING/ERROR/ADVICE), where it occurred (location), contextual details, and any solution text the reporter attached. This turns an unscannable wall of warnings into an expandable tree. ## Why it matters For a plugin author, the practical takeaway is: anything you report through the Problems API automatically shows up here, deduplicated and grouped, with no extra work. For a build engineer, it is the first place to look when a build prints "problems were reported" — open the HTML, not the raw log.

  • What happens to the report if a build reports zero problems?
    No report file is written and no link is printed — Gradle only generates the HTML when at least one problem was reported during that build.
  • Why is the file self-contained rather than referencing external CSS/JS?
    So it can be opened directly, emailed, or uploaded as a single CI artifact with no broken asset links or directory dependencies.

Think of the console as a stream of sticky notes flying past; the Problems Report is the corkboard where every note is pinned, sorted, and grouped so you can actually read them after the build.

saying these in an interview costs you the question

  • Claiming the report is always generated even with no problems.
  • Saying it lives in each subproject's build dir rather than the root project's build/reports/problems/.

context

open as a page

What is Gradle's Problems API and why would a plugin author report a structured problem instead of just throwing an exception or logging a warning?

level: juniorimportance: must knowfreq 35%

basics

~20 s

The Problems API lets a plugin report build issues as structured data (an ID, a message, severity, location) instead of plain text. Gradle then surfaces them uniformly in the console, the HTML report, IDEs, and the Tooling API.

open as a page

When reporting a structured problem with Gradle's Problems API, what severity levels can you assign via the ProblemSpec, and what does each one mean for the build?

level: juniorimportance: must knowfreq 35%

basics

~20 s

Severity is set with spec.severity(...) using the Severity enum: WARNING, ERROR, and ADVICE. ERROR signals a real failure, WARNING a concern, and ADVICE a hint/suggestion. It classifies the problem; it does not by itself fail the build.

open as a page

How does the Problems Report group entries, and what role does ProblemId (group + id) play in how problems surface to consumers?

level: middleimportance: must knowfreq 40%

basics

~20 s

Each reported problem carries a ProblemId — a stable id plus a ProblemGroup. The report uses that grouping to cluster problems of the same kind under shared headings, so consumers see a tree instead of a flat list.

open as a page

How do you obtain the Problems service inside a plugin or task, and why can't you just instantiate it?

level: middleimportance: must knowfreq 30%

basics

~10 s

You don't create it — Gradle injects it. Add a constructor parameter of type Problems annotated with @Inject on your Plugin or Task (using an abstract class), and Gradle's service registry supplies the instance.

open as a page

What are ProblemId and ProblemGroup, and why does giving a problem a stable identity matter?

level: middleimportance: must knowfreq 28%

basics

~20 s

A ProblemGroup is a namespace (e.g. your plugin's category) and a ProblemId is a stable identity within it — a name plus human displayName. The stable ID lets Gradle and IDEs group, count, and deduplicate the same kind of problem.

open as a page

How do you attach a source location to a structured problem so an IDE can point the user at the exact file and line?

level: middleimportance: must knowfreq 30%

basics

~10 s

On the ProblemSpec you call location methods like spec.fileLocation(path) or spec.lineInFileLocation(path, line, column). These attach a typed location object so IDEs can render a clickable link to the offending file/line.

open as a page

What does the --problems-report console link give you, and how does it relate to the terse summary lines Gradle prints?

level: middleimportance: should knowfreq 30%

basics

~10 s

Gradle prints a clickable file:// link to the aggregated problems-report.html. It connects the short console summary (like 'deprecated features were used') to the full structured detail in the HTML.

open as a page

When reporting a problem, what is the difference between contextualLabel and details, and how do they relate to the ProblemId's displayName?

level: middleimportance: should knowfreq 22%

basics

~20 s

The ProblemId displayName is the fixed category label. contextualLabel is the short, occurrence-specific headline (what's wrong here). details is longer explanatory text expanding on it. The label is the summary line; details is the body.

open as a page

Beyond saying what's wrong, how does the Problems API let you tell the user how to fix it and where to read more?

level: middleimportance: should knowfreq 22%

basics

~10 s

On the ProblemSpec you call solution("...") to give actionable fix advice (callable multiple times) and documentedAt("https://...") to attach a documentation link. Consumers surface these as suggestions and a 'learn more' link.

open as a page

How would you make the Problems Report useful in CI, and what makes it well-suited (or not) to that role?

level: seniorimportance: should knowfreq 25%

basics

~10 s

Archive build/reports/problems/problems-report.html as a CI artifact so reviewers open one self-contained page instead of scrolling logs. It is well-suited because the file is single, self-contained, and grouped.

open as a page

Walk through reporting a non-fatal problem versus a fatal one with the Problems API. When do you use report() versus throwing()?

level: seniorimportance: should knowfreq 24%

basics

~20 s

Use reporter.report(id) { ... } for non-fatal diagnostics (warnings/advice) — it records the structured problem but the build continues. Use reporter.throwing(exception, id) { ... } when the issue must fail the build — it records the same structured data and throws.

open as a page

Your plugin detects a fatal misconfiguration. Walk through how you'd emit an ERROR-severity structured problem AND fail the build, and contrast it with merely reporting it.

level: seniorimportance: should knowfreq 18%

basics

~10 s

Set severity(Severity.ERROR) on the spec, then use reporter.throwing(exception) (passing a RuntimeException) so Gradle records the structured problem and then throws to fail the build. reporter.report(...) would only record it and let the build continue.

open as a page

Why do Gradle's own deprecation warnings and configuration-cache problems show up in the Problems Report, and what does that imply for plugin authors?

level: seniorimportance: nice to knowfreq 18%

basics

~20 s

Gradle routes its own deprecations and configuration-cache issues through the same Problems API, so they land in the same aggregated report as plugin-reported problems. For authors, it means your problems appear alongside Gradle's, consistently grouped.

open as a page

What makes a Problems-API diagnostic 'actionable' for an IDE, and which ProblemSpec facets would you set to achieve that across a plugin?

level: seniorimportance: nice to knowfreq 12%

basics

~20 s

An actionable diagnostic sets a stable id+label, a severity, a precise location (lineInFileLocation), one or more solutions, and a documentedAt link — so an IDE can navigate to it, show the fix, and link the docs instead of parsing console text.

open as a page

Your organization has several plugins that emit dozens of logger.warn warnings. How would you adopt the Problems API across them, and what design choices keep the resulting diagnostics coherent?

level: principalimportance: nice to knowfreq 12%

basics

~20 s

Define a shared ProblemGroup taxonomy and stable ProblemId naming across plugins, inject Problems through a common base, migrate warnings incrementally (keeping ids stable), and keep occurrence-specific data in contextualLabel/details/location so consumers can group and aggregate consistently.

open as a page