apache/maven · error · IntrospectionException

The token '%s' at position '%d' refers to a java.util.List o

Error message

The token '%s' at position '%d' refers to a java.util.List or an array, but the value seems is an instance of '%s'

What it means

Companion of the Map error: an expression token indexes into what should be a List or array, but the value at that position is neither, or the bracketed token is not a valid list index. IntrospectionException reports the token, its position, and the actual class, aborting interpolation of the whole expression.

Source

Thrown at compat/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/reflection/ReflectionValueExtractor.java:267

            int index = Integer.parseInt(indexStr);

            if (value.getClass().isArray()) {
                return Array.get(value, index);
            }

            if (value instanceof List list) {
                return list.get(index);
            }
        } catch (NumberFormatException | IndexOutOfBoundsException e) {
            return null;
        }

        final String message = String.format(
                "The token '%s' at position '%d' refers to a java.util.List or an array, but the value "
                        + "seems is an instance of '%s'",
                expression.subSequence(from, to), from, value.getClass());

        throw new IntrospectionException(message);
    }

    private static Object getPropertyValue(Object value, String property) throws IntrospectionException {
        if (value == null || property == null || property.isEmpty()) {
            return null;
        }

        ClassMap classMap = getClassMap(value.getClass());
        String methodBase = Character.toTitleCase(property.charAt(0)) + property.substring(1);
        try {
            for (String prefix : Arrays.asList("get", "is", "to", "as")) {
                Method method = classMap.findMethod(prefix + methodBase);
                if (method != null) {
                    return method.invoke(value, OBJECT_ARGS);
                }
            }
            return null;
        } catch (InvocationTargetException e) {

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Check the actual type at the failing position (named in the message) and use plain property access for beans
  2. Use bracket indexing only on documented List/array values such as ${project.repositories[0].url}
  3. Fix or remove stale expressions copied from other projects
  4. Validate interpolated expressions after model or plugin upgrades with help:effective-pom

Example fix

<!-- before: index applied to a non-list value -->
<name>${project.artifactId[0]}</name>

<!-- after: index only List/array-valued paths -->
<url>${project.repositories[0].url}</url>
Defensive patterns

Strategy: try-catch

Type guard

static boolean isIndexablePath(Object node) {
    return node != null && (node instanceof List<?> || node.getClass().isArray());
}

Try / catch

try {
    Object v = ReflectionValueExtractor.evaluate(expr, model);
} catch (IntrospectionException e) {
    // token expected a List/array but found another type: fix the expression
    log.warn("Bad indexed expression {}: {}", expr, e.getMessage());
    return defaultValue; // or surface to the user
}

Prevention

When it happens

Trigger: Expressions such as ${project.artifactId[0]} or ${something.field[0]} where the indexed value is not a List or array; note that a non-numeric bracket token on a List also swallows into this path before the throw.

Common situations: Indexing expressions against fields whose type changed between versions; ${project.repositories[0].url}-style paths copied onto non-list values; stale plugin documentation showing bracket syntax.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/cc6f847a4dd3351e. Report an issue: GitHub.