theonedev/onedev · error · ValidationException

Property path must provide index or map key.

Error message

Property path must provide index or map key.

What it means

Thrown when a property path traverses an iterable/map property (the path node is marked iterable) but that node supplies neither an index nor a map key. To reach an element inside a container the path must specify which element is meant.

Solutions

  1. Add an index or key selector to the path segment: "items[0].name" or "items[myKey].name".
  2. If you want to validate all elements, validate the container property itself (cascade) rather than one path.
  3. Fix programmatic Path/Node construction so iterable nodes always carry index or key.

Example fix

// before
validator.validateProperty(order, "items.name");

// after
validator.validateProperty(order, "items[0].name");
Defensive patterns

Strategy: validation

Validate before calling

// container segments must carry [index] or [key]
Pattern sel = Pattern.compile("\\w+\\[.+?\\]");
boolean hasSelector(String path) {
    for (String seg : path.split("\\.")) {
        if (seg.endsWith("[]") || seg.matches("\\w+")) continue; // crude check
        if (!sel.matcher(seg).find() && isContainerSegment(seg)) return false;
    }
    return true;
}

Type guard

null

Try / catch

try {
    validator.validateProperty(bean, path);
} catch (ValidationException e) {
    if (e.getMessage().contains("must provide index or map key")) {
        // rewrite path as items[0].name or items[key].name
    } else throw e;
}

Prevention

When it happens

Trigger: validateProperty with a path like "items.name" (missing the [<index>] or [<key>] selector) where 'items' is a List/Map and the path node is treated as iterable, e.g. "items.name" instead of "items[0].name" or "items[code].name".

Common situations: Hand-built path strings missing bracket selectors, programmatic Path construction that sets isIterable without index/key, copying paths from constraint violation messages that omitted selectors.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/02f1280c5fee4875. Report an issue: GitHub.

Appendix: source

Thrown at server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java:1238

				value = getCascadableValue( validationContext, value, propertyMetaData.getCascadables().iterator().next() );
				if ( value == null ) {
					throw LOG.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath );
				}
				clazz = value.getClass();

				// if we are in the case of an iterable and we want to validate an element of this iterable, we have to get the
				// element value
				if ( propertyPathNode.isIterable() ) {
					propertyPathNode = (NodeImpl) propertyPathIter.next();

					if ( propertyPathNode.getIndex() != null ) {
						value = ReflectionHelper.getIndexedValue( value, propertyPathNode.getIndex() );
					}
					else if ( propertyPathNode.getKey() != null ) {
						value = ReflectionHelper.getMappedValue( value, propertyPathNode.getKey() );
					}
					else {
						throw LOG.getPropertyPathMustProvideIndexOrMapKeyException();
					}

					if ( value == null ) {
						throw LOG.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath );
					}

					clazz = value.getClass();
					beanMetaData = beanMetaDataManager.getBeanMetaData( clazz );
					propertyMetaData = getBeanPropertyMetaData( beanMetaData, propertyPathNode );
				}
				else {
					beanMetaData = beanMetaDataManager.getBeanMetaData( clazz );
				}
			}
		}

		if ( propertyMetaData == null ) {
			// should only happen if the property path is empty, which should never happen

View on GitHub (pinned to d44925c47c)