junit-team/junit5 · error · ExtensionContextException
%s
Error message
%s
What it means
A generic wrapper thrown by NamespaceAwareStore.accessStore: any operation on the ExtensionContext.Store (get, put, getOrComputeIfAbsent, remove, computeIfAbsent, etc.) that fails inside the underlying NamespacedHierarchicalStore with a NamespacedHierarchicalStoreException is rethrown as an ExtensionContextException carrying the same message. The '%s' message is whatever the store layer produced (type mismatch, null key, etc.).
Source
Thrown at junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java:123
Preconditions.notNull(key, "key must not be null");
Supplier<@Nullable Object> action = () -> this.valuesStore.remove(this.namespace, key);
return this.<@Nullable Object> accessStore(action);
}
@Override
public <T> @Nullable T remove(Object key, Class<T> requiredType) {
Preconditions.notNull(key, "key must not be null");
Preconditions.notNull(requiredType, "requiredType must not be null");
Supplier<@Nullable T> action = () -> this.valuesStore.remove(this.namespace, key, requiredType);
return this.<@Nullable T> accessStore(action);
}
private <T extends @Nullable Object> T accessStore(Supplier<T> action) {
try {
return action.get();
}
catch (NamespacedHierarchicalStoreException e) {
throw new ExtensionContextException(e.getMessage(), e);
}
}
}
View on GitHub (pinned to f070c699a0)
Solutions
- Inspect the wrapped NamespacedHierarchicalStoreException message - it states the actual constraint violated.
- Use a consistent type per (namespace, key) pair across all extensions sharing the namespace.
- Avoid sharing mutable stored objects across parallel test threads without external synchronization.
Example fix
// before
store.put("cfg", List.of("a"));
Map<String,String> cfg = store.get("cfg", Map.class); // type mismatch -> wrapped
// after
store.put("cfg", Map.of("k","v"));
Map<String,String> cfg = store.get("cfg", Map.class); Defensive patterns
Strategy: try-catch
Validate before calling
Object stored = store.get(key);
Class<?> expected = Map.class;
if (stored != null && !expected.isInstance(stored)) {
throw new IllegalStateException("Stored " + stored.getClass() + " is not " + expected);
} Type guard
Object v = store.get("cfg");
if (!(v instanceof Map<?,?> m)) {
throw new IllegalStateException("expected Map, got " + (v == null ? "null" : v.getClass()));
} Try / catch
try {
Map<String,String> cfg = store.get("cfg", Map.class);
} catch (ExtensionContextException e) {
log.error("store access failed: {}", e.getCause());
throw e;
} Prevention
- Use a single type per (namespace, key) pair across extensions.
- Prefer typed accessors get(key, requiredType) over raw get(key) plus casts.
- Avoid sharing mutable stored objects across parallel test threads without synchronization.
When it happens
Trigger: Any Store.<operation> where the underlying store throws - e.g. get(key, requiredType) with a stored value that is not assignable to requiredType, or computeIfAbsent racing on a null defaultCreator result. accessStore catches NamespacedHierarchicalStoreException and wraps it.
Common situations: Storing mixed types under the same key and later fetching with the wrong requiredType; one extension stores a List and another fetches with Map.class; concurrent modification of the store from parallel test threads when the store is not thread-safe for the operation.
Related errors
- Object stored under key [%s] is not of required type [%s], b
- Failed to publish path
- TestInstanceFactory [%s] failed to return an instance of [%s
- Failed to close extension context
- ParameterResolver [%s] resolved a value of type [%s] for par
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/97163674993c587e.
Report an issue: GitHub.