Expected behavior
When a translatable chat component is flattened, placeholders like %1$s resolve against the component's argument list. Out-of-range positive indices are dropped (idx < args.size()), and malformed indices are dropped too (a NumberFormatException catch). A %0$s placeholder should be treated the same way and dropped, not crash the flattening.
Observed/Actual behavior
In io.papermc.paper.adventure.PaperAdventure#FLATTENER, the argument index is computed as Integer.parseInt(argIdx) - 1. That makes %0$s produce index -1. The only guard is if (idx < args.size()), and -1 passes that check whenever the component has at least one argument, so args.get(-1) throws:
java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length N
The NumberFormatException handler exists specifically to drop malformed placeholders, so the missing lower bound reads like an oversight. A translation entry like "custom.key": "You have %0$s items" in a resource pack, plus a translatable component that has arguments, will throw whenever that component is flattened (chat, console output, item tooltips, command feedback).
I reproduced the exact logic standalone: %0$s -> idx = -1, the idx < args.size() check passes with a non-empty argument list, and args.get(-1) throws.
Steps/models to reproduce
- Create a translatable component with at least one argument whose translation value contains
%0$s.
- Flatten it, e.g. through the plain text or legacy section serializer.
- Observe the IndexOutOfBoundsException.
Plugin and Datapack List
No plugins or datapacks needed.
Paper version
main branch at 6c8d413 (after 26.1.2). Code-level bug in PaperAdventure.java, not a runtime server issue, so there is no /version output to paste.
Other
One-line fix is to add idx >= 0 && to the guard. I can open a PR for it if that works.
Expected behavior
When a translatable chat component is flattened, placeholders like
%1$sresolve against the component's argument list. Out-of-range positive indices are dropped (idx < args.size()), and malformed indices are dropped too (aNumberFormatExceptioncatch). A%0$splaceholder should be treated the same way and dropped, not crash the flattening.Observed/Actual behavior
In
io.papermc.paper.adventure.PaperAdventure#FLATTENER, the argument index is computed asInteger.parseInt(argIdx) - 1. That makes%0$sproduce index -1. The only guard isif (idx < args.size()), and -1 passes that check whenever the component has at least one argument, soargs.get(-1)throws:The
NumberFormatExceptionhandler exists specifically to drop malformed placeholders, so the missing lower bound reads like an oversight. A translation entry like"custom.key": "You have %0$s items"in a resource pack, plus a translatable component that has arguments, will throw whenever that component is flattened (chat, console output, item tooltips, command feedback).I reproduced the exact logic standalone:
%0$s->idx = -1, theidx < args.size()check passes with a non-empty argument list, andargs.get(-1)throws.Steps/models to reproduce
%0$s.Plugin and Datapack List
No plugins or datapacks needed.
Paper version
main branch at 6c8d413 (after 26.1.2). Code-level bug in
PaperAdventure.java, not a runtime server issue, so there is no/versionoutput to paste.Other
One-line fix is to add
idx >= 0 &&to the guard. I can open a PR for it if that works.