{"record":{"id":"97163674993c587e","repo":"junit-team/junit5","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":"ExtensionContextException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java","lineNumber":123,"sourceCode":"\t\tPreconditions.notNull(key, \"key must not be null\");\n\t\tSupplier<@Nullable Object> action = () -> this.valuesStore.remove(this.namespace, key);\n\t\treturn this.<@Nullable Object> accessStore(action);\n\t}\n\n\t@Override\n\tpublic <T> @Nullable T remove(Object key, Class<T> requiredType) {\n\t\tPreconditions.notNull(key, \"key must not be null\");\n\t\tPreconditions.notNull(requiredType, \"requiredType must not be null\");\n\t\tSupplier<@Nullable T> action = () -> this.valuesStore.remove(this.namespace, key, requiredType);\n\t\treturn this.<@Nullable T> accessStore(action);\n\t}\n\n\tprivate <T extends @Nullable Object> T accessStore(Supplier<T> action) {\n\t\ttry {\n\t\t\treturn action.get();\n\t\t}\n\t\tcatch (NamespacedHierarchicalStoreException e) {\n\t\t\tthrow new ExtensionContextException(e.getMessage(), e);\n\t\t}\n\t}\n\n}\n","sourceCodeStart":105,"sourceCodeEnd":128,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/NamespaceAwareStore.java#L105-L128","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nstore.put(\"cfg\", List.of(\"a\"));\nMap<String,String> cfg = store.get(\"cfg\", Map.class); // type mismatch -> wrapped\n// after\nstore.put(\"cfg\", Map.of(\"k\",\"v\"));\nMap<String,String> cfg = store.get(\"cfg\", Map.class);","handlingStrategy":"try-catch","validationCode":"Object stored = store.get(key);\nClass<?> expected = Map.class;\nif (stored != null && !expected.isInstance(stored)) {\n    throw new IllegalStateException(\"Stored \" + stored.getClass() + \" is not \" + expected);\n}","typeGuard":"Object v = store.get(\"cfg\");\nif (!(v instanceof Map<?,?> m)) {\n    throw new IllegalStateException(\"expected Map, got \" + (v == null ? \"null\" : v.getClass()));\n}","tryCatchPattern":"try {\n    Map<String,String> cfg = store.get(\"cfg\", Map.class);\n} catch (ExtensionContextException e) {\n    log.error(\"store access failed: {}\", e.getCause());\n    throw e;\n}","preventionTips":["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."],"tags":["store","namespace","type-mismatch","extension-context"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}