junit-team/junit5 · error · NamespacedHierarchicalStoreException
Object stored under key
Error message
Object stored under key [%s] is not of required type [%s], but was [%s]: %s
What it means
NamespacedHierarchicalStore.get(key, requiredType) throws when the stored value is not assignable to the requested type. The store is type-erased internally; the caller asks for a Class<T> and the implementation checks isAssignableTo(value, requiredType). The message reports the key, the requested type, the actual type, and the value.
Solutions
- Inspect the message: it gives the actual stored class - update the requested type to match, or change what is stored.
- Use a unique key per extension/value to avoid collisions (e.g. include the extension class or a constant owned by the extension).
- If the value type legitimately changed, clear the old store entry or use a new Namespace/key pair.
- Verify getOrComputeIfAbsent's supplier returns the same type you later request.
Example fix
// before store.put(Namespace.GLOBAL, "cfg", 42); // Integer String s = store.get(Namespace.GLOBAL, "cfg", String.class); // throws // after Integer i = store.get(Namespace.GLOBAL, "cfg", Integer.class);
Defensive patterns
Strategy: type-guard
Validate before calling
// Check the stored type before requesting it
Object raw = store.get(namespace, key, Object.class);
if (raw != null && !requiredType.isInstance(raw)) {
throw new IllegalStateException("stored type is " + raw.getClass());
}
T value = store.get(namespace, key, requiredType); Type guard
static <T> boolean storeHasType(NamespacedHierarchicalStore s, Namespace n, Object k, Class<T> t) {
Object v = s.get(n, k, Object.class);
return v == null || t.isInstance(v);
} Try / catch
try {
return store.get(namespace, key, requiredType);
} catch (NamespacedHierarchicalStoreException e) {
// wrong type: read message, migrate the key, or use a new key
} Prevention
- Use a unique key per extension/value (combine with the extension class).
- Make getOrComputeIfAbsent suppliers return the exact type you later request.
- When changing a value's type across versions, migrate to a new key.
When it happens
Trigger: Calling store.get(namespace, key, SomeType.class) where the value previously stored under (namespace, key) via put/getOrComputeIfAbsent is of a different type. Common when an ExtensionContext / EngineContext store key is reused across extensions with different value types, or when the stored type changed between versions.
Common situations: Two extensions store different value types under the same Namespace+key; a version upgrade changed the stored value class; a test reads a value with the wrong Class token after a refactor; misuse of getOrComputeIfAbsent where the supplier returns an incompatible type.
Related errors
- %s
- A NamespacedHierarchicalStore cannot be modified or queried…
- Argument at index [ ] with value [ ] and type [ ] could not…
- Can only resolve @TempDir
- Cannot convert null to primitive value of type
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/ff4d97ac53def727.
Report an issue: GitHub.
Appendix: 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 f070c699a0)