PathNotRepresentableException
The expression is well formed and names something this path type cannot hold.
The distinction this exists to make is between a typo and a limit, and it is invisible to a caller today: CatalogPath.parse, VariantPath.parse and JsonPathQuery.compile all report every failure as an IllegalArgumentException, so "you misspelled the field" and "a filter selects documents, not positions" arrive as the same type and differ only in prose. A CLI that wants to answer the first with fix your path and the second with use the other flag has to match on the message, and matching on a message is not matching.
JsonPathLimitExceededException made the same argument one case earlier — it is distinct so that too expensive can be told from malformed and from will not decode — and closes with the line this class is the fourth application of: separating them by message is not separating them.
Why a subclass of IllegalArgumentException and not a new hierarchy. Every module here has a sealed base — CatalogException, VariantException, IndexException, StoreException — and none of them can be joined from outside its module, which is a property CatalogException's own documentation asks to keep. More to the point, a supertype cannot be retrofitted under an exception callers already catch, and callers already catch this one: every existing catch (IllegalArgumentException) and catch (RuntimeException) around a path parse keeps working unchanged, and a caller that wants the distinction opts in by catching the narrower type first. Subclassing is the additive direction; reparenting is not.
Not part of any module's sealed hierarchy on purpose. Those describe state a store got into. This describes an argument the caller passed, which is what IllegalArgumentException is for.