typetools / typetools/checker-framework
i18nformat.key.not.found reported for ResourceBundle.getString(key) when key is a valid constant passed through variable indirection
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 440
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 134
Description
Description
The I18n Formatter Checker reports i18nformat.key.not.found for ResourceBundle.getString(key) even when key is a valid constant defined in the resource bundle.
This happens because the key is passed through variable indirection, and the checker fails to recognize it as a valid compile-time constant.
Reproduction
In Checkstyle, we use a pattern like this:
// DesignForExtensionCheck.java
public static final String MSG_KEY = "design.forExtension";
log(ast, MSG_KEY, className, methodName);
Call Flow:
AbstractCheck.log(...) -> new Violation(key) -> Violation.getViolation() -> new LocalizedMessage(key).getMessage() -> bundle.getString(key)
Even though design.forExtension exists in messages.properties, the checker reports:
i18nformat.key.not.found
Expected Behavior
The checker should ideally recognize that the key is valid, or provide a way to annotate the variable as a known property key without requiring a literal.
Workaround attempted
Switching to bundle.getObject(key) removes the i18nformat.key.not.found error because getObject is not annotated with @I18nMakeFormat in the annotated JDK. However, this does not solve the root issue (key validity proof) and only bypasses the formatter check.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the ResourceBundle.getString(key) path described in the issue and inspect DesignForExtensionCheck.java, then compare the key against messages.properties. Reproduce the false positive and trace how variable indirection and @I18nMakeFormat are handled. Done means a valid constant key no longer triggers i18nformat.key.not.found, with coverage for this call flow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- internationalization
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100