quarkusio/quarkus · error · UnableToParseMethodException

Unable to parse query with limiting results clause. Offendin

Error message

Unable to parse query with limiting results clause. Offending method is ${repositoryMethodDescription}.

What it means

When First/Top is used in a find method, the text between the First/Top keyword and 'By' must parse as an integer limit (empty means 1). If Integer.valueOf fails — e.g. findTopABCByName — parse() throws UnableToParseMethodException.

Source

Thrown at extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/MethodNameParser.java:125

        int minFirstOrTopIndex = Math.min(indexOfOrMaxValue(methodName, "First"), indexOfOrMaxValue(methodName, "Top"));
        // 'First' and 'Top' could be part of a field name, so we only consider them as part of a top query
        // if they are found before 'By'
        if (minFirstOrTopIndex < byIndex) {
            if (queryType != QueryType.SELECT) {
                throw new UnableToParseMethodException(
                        "When 'Top' or 'First' is specified, the query must be a find query. Offending method is "
                                + repositoryMethodDescription + ".");
            }
            try {
                String topCountStr = methodName.substring(minFirstOrTopIndex, byIndex)
                        .replace("Top", "").replace("First", "");
                if (topCountStr.isEmpty()) {
                    topCount = 1;
                } else {
                    topCount = Integer.valueOf(topCountStr);
                }
            } catch (Exception e) {
                throw new UnableToParseMethodException(
                        "Unable to parse query with limiting results clause. Offending method is "
                                + repositoryMethodDescription + ".");
            }
        }

        if (methodName.substring(0, byIndex).contains("Distinct")) {
            throw new UnableToParseMethodException(
                    "Distinct is not yet supported. Offending method is " + repositoryMethodDescription + ".");
        }

        // handle 'AllIgnoreCase'
        String afterByPart = methodName.substring(byIndex + 2);
        boolean allIgnoreCase = false;
        if (afterByPart.contains(ALL_IGNORE_CASE)) {
            allIgnoreCase = true;
            afterByPart = afterByPart.replace(ALL_IGNORE_CASE, "");
        }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Use a numeric limit: findTop5ByStatus or findFirst10ByName (bare Top/First means 1)
  2. Spell the number as digits immediately after Top/First, nothing else between it and 'By'
  3. If a non-numeric limit expression is needed, switch to @Query with pagination/limit at the call site

Example fix

// before
List<User> findTopFiveByStatus(String status);
// after
List<User> findTop5ByStatus(String status);
Defensive patterns

Strategy: validation

Validate before calling

// text between Top/First and 'By' must be empty or a positive integer
String s = methodName.substring(minIdx, byIndex).replace("Top","").replace("First","");
if (!s.isEmpty()) Integer.parseInt(s); // throws before build if invalid

Try / catch

// Build-time failure; use digits:
// List<User> findTop5ByStatus(String status);

Prevention

When it happens

Trigger: `findTopTwoByName`, `findFirst10thBy...` or any non-numeric garbage between Top/First and 'By' in a SELECT derived-query method name.

Common situations: Writing limits as words ('TopFive'); typos like 'Top1O' (letter O); leftover characters from renaming; accidental field-name fragment between Top and By.

Understand the failure class

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/1d52b21ee1bafb1d. Report an issue: GitHub.