junit-team/junit5 · error · NamespacedHierarchicalStoreException

Object stored under key [%s] is not of required type [%s], b

Error message

Object stored under key [%s] is not of required type [%s], but was [%s]: %s

What it means

Thrown by NamespacedHierarchicalStore.castNonNullToRequiredType (line 484-496) as a NamespacedHierarchicalStoreException when a stored value is not assignable to the requested requiredType. It names the key, the required type, the actual type, and the value's toString(). This is the ExtensionContext.Store type-mismatch error hit by Jupiter extensions and store users.

Source

Thrown at junit-platform-engine/src/main/java/org/junit/platform/engine/support/store/NamespacedHierarchicalStore.java:493

	private <T> @Nullable T castToRequiredType(Object key, @Nullable Object value, Class<T> requiredType) {
		Preconditions.notNull(requiredType, "requiredType must not be null");
		if (value == null) {
			return null;
		}
		return castNonNullToRequiredType(key, value, requiredType);
	}

	@SuppressWarnings("unchecked")
	private <T, V> T castNonNullToRequiredType(Object key, V value, Class<T> requiredType) {
		if (isAssignableTo(value, requiredType)) {
			if (requiredType.isPrimitive()) {
				return (T) requireNonNull(getWrapperType(requiredType)).cast(value);
			}
			return requiredType.cast(value);
		}
		// else
		throw new NamespacedHierarchicalStoreException(
			"Object stored under key [%s] is not of required type [%s], but was [%s]: %s".formatted(key,
				requiredType.getName(), value.getClass().getName(), value));
	}

	private void rejectIfClosed() {
		if (this.closed) {
			throw new NamespacedHierarchicalStoreException(
				"A NamespacedHierarchicalStore cannot be modified or queried after it has been closed");
		}
	}

	private record CompositeKey<N>(N namespace, Object key) {

		CompositeKey {
			Preconditions.notNull(namespace, "namespace must not be null");
			Preconditions.notNull(key, "key must not be null");
		}

View on GitHub (pinned to 956246301e)

Solutions

  1. Namespace your Store keys (e.g. 'com.acme.MyExt.myResource') so unrelated extensions cannot collide on the same key.
  2. Ensure the same key is always stored with the same type across all extensions in your codebase.
  3. Call the untyped get(namespace, key) and instanceof-check before casting, rather than the typed overload, if type may vary.
  4. Use computeIfAbsent with a consistent creator so the stored type is deterministic.

Example fix

// before
store.put(MY_NS, "config", "42");
Integer n = store.get(MY_NS, "config", Integer.class); // throws: actual String

// after
store.put(MY_NS, "config", 42);
Integer n = store.get(MY_NS, "config", Integer.class); // ok
Defensive patterns

Strategy: type-guard

Validate before calling

Object raw = store.get(MY_NS, key);
if (raw != null && !SomeType.class.isInstance(raw)) {
    throw new IllegalStateException("stored value under " + key + " is " + raw.getClass());
}
SomeType value = store.get(MY_NS, key, SomeType.class);

Type guard

static <T> Optional<T> getIfType(ExtensionContext.Store store, Object key, Class<T> type) {
    Object v = store.get(key);
    return type.isInstance(v) ? Optional.of(type.cast(v)) : Optional.empty();
}

Try / catch

try {
    return store.get(key, SomeType.class);
} catch (NamespacedHierarchicalStoreException e) {
    // message tells actual vs required type
    log.warn("type mismatch in store for {}", key, e);
    return null;
}

Prevention

When it happens

Trigger: Calling store.get(namespace, key, SomeType.class), getOrComputeIfAbsent(..., requiredType), computeIfAbsent(..., requiredType), or remove(..., requiredType) where the value previously stored under (namespace, key) is of an incompatible class (e.g. stored a String but requested Integer, or stored a List and requested a custom type).

Common situations: Two extensions using the same Store key for different value types; refactoring an extension to change the stored type without migrating existing keys; serializable/snapshot scenarios where the restored type differs; copy-paste of a Store key string across unrelated extensions.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/ff4d97ac53def727.json. Report an issue: GitHub.