| name | review-fixes-native-image-run-fail |
| description | Review pull requests with the `fixes-native-image-run-fail` label in graalvm-reachability-metadata. Use when asked to review or triage a PR that fixes a native-image runtime failure for an existing library version update. Focus on validating the runtime/native fix, keeping the diff scoped, and ensuring the dynamic-access coverage percentage does not drop by more than 20 percentage points between the previously tested version and the new version. |
| argument-hint | [pr-number-or-url] |
Review fixes-native-image-run-fail PRs
These PRs repair metadata or tests after an existing library version compiles and builds a native image, but the native image fails when the test runs. Review them more lightly than library-new-request PRs: the library is already supported, so the goal is to restore native-image behavior for a newer version while preserving existing dynamic-access coverage.
The PR number or URL can be passed as an optional argument (for example, 1234, https://github.com/oracle/graalvm-reachability-metadata/pull/1234). If the user says "review this PR" without an argument, infer the PR from the surrounding conversation or gh pr status; only ask the user when it cannot be inferred. Use gh pr view <pr>, gh pr diff <pr>, and gh pr checks <pr> against the resolved PR throughout the workflow below.
Review Principles
- Confirm the PR has label
fixes-native-image-run-fail.
- Expect targeted metadata, resource, proxy, serialization, JNI, initialization, or test adjustments that make the native executable run successfully for the new version.
- Be more relaxed than
library-new-request: do not reject only because a test is inherited from older support, uses compatibility branches, or keeps an existing package layout.
- Do not accept fixes that hide the failing native path by skipping assertions, skipping native-image runtime execution, or weakening the test until the failure disappears.
- Treat dynamic-access coverage preservation as the main quality gate, compared by percentage only. Do not treat changes in absolute covered or total call counts as a drop. The new version should not report a coverage percentage more than 20 percentage points lower than the previously tested version unless the PR gives a concrete, credible reason.
- For numeric gates, compare the reported evidence as-is. Do not inspect generation filters, agent configuration, or metadata contents to second-guess why dynamic-access or metadata-count numbers are what they are.
- Compare total metadata entry counts between the previous metadata version and the new metadata version only as a severe-drop guardrail, using the counts reported in the PR description. When the PR reports both library metadata entries and test-only metadata entries, sum them for that version's total. Report metadata entry count issues only when the PR-reported new total metadata entry count has fewer than 25% as many entries as the PR-reported original count.
- A new version that reports zero dynamic-access calls (for example
dynamicAccess.totalCalls == 0, or a {} reachability-metadata.json with no claimed dynamic-access behavior) does not give enough information to judge whether metadata is unnecessary or whether a metadata-entry-count drop is meaningful. Dynamic-access stats can miss metadata required through transitive dependencies. Do not report a metadata-entry-count drop, and do not flag a shallow test or a test that exercises behavior outside the library's responsibility, as a blocking issue or human-intervention for such a library. The native-image runtime fix itself must still pass and must not be made green by skipping the native path or disabling native-image behavior.
- Accept only
reachability-metadata.json files as metadata files. Reject legacy native-image metadata config files such as reflect-config.json, resource-config.json, proxy-config.json, serialization-config.json, jni-config.json, or predefined-classes-config.json.
- Prefer concrete evidence from native run output, generated metadata, stats, and CI over style objections.
Workflow
-
Inspect the PR summary.
- Resolve the target PR from the optional argument, or infer it from context when possible.
- Confirm the PR has label
fixes-native-image-run-fail.
- Identify the target coordinate, the previous tested version, and the new tested version from the PR body, title, changed
index.json, metadata path, and test path.
- Gather files, reviews, inline comments, and CI checks.
-
Validate the diff scope.
- Expected files are usually limited to:
metadata/<group>/<artifact>/<version>/reachability-metadata.json
metadata/<group>/<artifact>/index.json
stats/<group>/<artifact>/<version>/stats.json
tests/src/<group>/<artifact>/<version>/**
- allowed Docker image entries or test resources only when the native test requires them
- Treat generated test project files such as
.gitignore, build.gradle, gradle.properties, settings.gradle, and user-code-filter.json as normal when they live under the target version's test directory.
- Accept metadata additions that are necessary for the new upstream version.
- Accept narrow test edits that keep the same behavior covered across old and new versions.
- Be suspicious of unrelated build logic, workflows, generated sources, other libraries, or broad refactors.
- Reject legacy native-image metadata config files. Metadata for generated support and test-only metadata must use
reachability-metadata.json.
- Reject or request changes if the PR fixes the native run by disabling the failing behavior.
-
Review the native-image fix.
- Confirm the metadata or test change matches the observed native runtime failure, such as missing reflection, resources, proxies, serialization constructors, JNI access, or class initialization behavior.
- Metadata additions should be specific enough to the target library behavior; do not require hand-minimized entries when generated metadata is coherent and validation passes.
- Test changes are acceptable when the upstream API or runtime behavior changed, but they must still exercise the native path that previously failed.
- Do not require the stricter
library-new-request rules about scaffold-only tests or test package placement unless the PR is also adding a new library.
-
Check dynamic-access coverage across versions.
- Compare
stats/<group>/<artifact>/<old-metadata-version>/stats.json and stats/<group>/<artifact>/<new-metadata-version>/stats.json when stats files are present in the PR or available on the branch.
- Compare
dynamicAccess.coverageRatio (or the percentage reported in the PR description) for the overall report and the dynamicAccess.breakdown entries for reflection, resources, proxies, serialization, JNI, or any other present report type. Use coveredCalls and totalCalls only to compute percentages; do not compare the absolute counts between versions.
- Do not use
user-code-filter.json, agent configuration, or metadata file contents to argue that the reported dynamic-access values are not comparable. Use the stats values as reported unless the stats are missing or stale.
- A coverage percentage drop of more than 20 percentage points for the new version is blocking unless the PR explains why the reduction is expected. Percentage drops of 20 points or less, and any reduction in absolute
coveredCalls or totalCalls, are not drops and must not be reported as regressions.
- If metadata fixes make the native run pass but the dynamic-access coverage percentage drops by more than 20 percentage points, ask for restored coverage first. Passing native execution is not enough by itself.
- If stats are missing or stale, ask for
generateLibraryStats or the relevant CI stats job before approving.
-
Compare metadata entry counts.
- Compare total metadata entry counts for the previous metadata version and the new metadata version from the PR description, matching summary fields such as
Metadata entries, legacy Entries or Entries found, Test-only metadata entries, Metadata entries (new ...), Test-only metadata entries (new ...), Previous library version metadata entries, and Previous library version test-only metadata entries.
- Treat each version's total as library metadata entries plus test-only metadata entries when both are reported.
- Do not manually count entries from metadata files.
- Do not use metadata file contents to argue that passing reported entry counts are incomplete.
- Do not require an exact match. Differences are normal when upstream APIs move, generated metadata is cleaned up, or dynamic-access totals change.
- Do not report metadata entry count issues unless the PR-reported new total metadata entry count is lower than 25% of the PR-reported original total metadata entry count.
- When the new total is below 25% of the original and the tests and dynamic-access stats still claim comparable coverage, ask for restored metadata or a concrete explanation of the API/package change.
- Skip this comparison entirely when the new version reports zero dynamic-access calls. A zero-call report gives too little information to judge metadata relevance, so a metadata-entry-count drop for it is not a reliable review signal and must not be reported or escalated.
- If the PR description does not report usable old and new metadata entry counts, do not infer them from metadata files; ask for refreshed PR summary evidence when the comparison is needed.
-
Check CI before deciding.
- Expected minimum: native-image compile and native test execution are green for the target coordinate.
- Metadata validation and Java tests should also pass for the changed coordinate.
- If current-defaults and future-defaults lanes both run, both should pass unless the PR clearly targets only one failing lane and the other failure is unrelated infrastructure noise.
- If CI is flaky but the diff and coverage comparison are sound, ask for a rerun instead of blocking on speculation.
Decision Rules
Approve when all of these are true:
- The PR is scoped to the target existing library and the native-image runtime failure it fixes.
- The native-image runtime path still executes meaningful library behavior.
- The dynamic-access coverage percentage does not drop by more than 20 percentage points between the previous and new tested versions, or a larger drop is convincingly explained by a changed upstream API surface.
- Total metadata entry counts are not below the 25% severe-drop threshold, or the reduction is convincingly explained by a changed upstream API surface, or the new version reports zero dynamic-access calls and the metadata-entry-count comparison is skipped.
- Required metadata, Java, native-image compile, and native-image run checks are green.
Request changes when any of these are true:
- The fix makes native execution pass by skipping the failing native path, disabling assertions, or removing coverage.
- The dynamic-access coverage percentage drops by more than 20 percentage points without a credible explanation and replacement coverage.
- Total metadata entry count drops below 25% of the original without a credible explanation for a new version that reports non-zero dynamic-access calls.
- Metadata additions are unrelated to the failure or affect other libraries without justification.
- CI failures indicate the native-image runtime problem is not actually fixed.
Ask for follow-up instead of rejecting when:
- Stats needed for the old/new version comparison are missing or stale.
- CI failed in a way that looks like infrastructure noise.
- The API or native runtime change is plausible but the PR does not explain why a coverage percentage drop of more than 20 percentage points is expected.
- Total metadata entry count drops below 25% of the original for a new version that reports non-zero dynamic-access calls, but the changed upstream API surface makes the reduction plausible.
Output Style
Keep comments short and factual:
- For coverage drops: report only drops where the new version's coverage percentage is more than 20 percentage points below the previous version's; cite the old and new percentages, and ask for either restored coverage or a concrete explanation. Do not comment on changes in absolute covered or total call counts.
- For metadata entry drops: report only drops where the new version reports non-zero dynamic-access calls and the new total metadata has fewer than 25% as many entries as the previous version's total metadata; cite the old and new counts, and ask for either restored metadata or a concrete explanation of the API/runtime-surface change. Do not report a metadata entry drop, and do not flag a shallow or off-target test, when the new version reports zero dynamic-access calls, because that signal is not enough to judge metadata relevance.
- For native skips: say that the PR avoids the failing native path instead of fixing it, so it does not demonstrate native-image runtime coverage.
- For unrelated changes: say the PR should stay scoped to the
fixes-native-image-run-fail repair and remove unrelated files.
- For legacy metadata files: say that metadata must use
reachability-metadata.json and ask for old config files such as reflect-config.json or resource-config.json to be replaced.
- For missing stats: ask for regenerated library stats or CI evidence before approval.