{"record":{"id":"ff4d97ac53def727","repo":"junit-team/junit5","slug":"object-stored-under-key-s-is-not-of-required-ty","errorCode":null,"errorMessage":"Object stored under key [%s] is not of required type [%s], but was [%s]: %s","messagePattern":"Object stored under key \\[(.+?)\\] is not of required type \\[(.+?)\\], but was \\[(.+?)\\]: (.+?)","errorType":"exception","errorClass":"NamespacedHierarchicalStoreException","httpStatus":null,"severity":"error","filePath":"junit-platform-engine/src/main/java/org/junit/platform/engine/support/store/NamespacedHierarchicalStore.java","lineNumber":493,"sourceCode":"\n\tprivate <T> @Nullable T castToRequiredType(Object key, @Nullable Object value, Class<T> requiredType) {\n\t\tPreconditions.notNull(requiredType, \"requiredType must not be null\");\n\t\tif (value == null) {\n\t\t\treturn null;\n\t\t}\n\t\treturn castNonNullToRequiredType(key, value, requiredType);\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\tprivate <T, V> T castNonNullToRequiredType(Object key, V value, Class<T> requiredType) {\n\t\tif (isAssignableTo(value, requiredType)) {\n\t\t\tif (requiredType.isPrimitive()) {\n\t\t\t\treturn (T) requireNonNull(getWrapperType(requiredType)).cast(value);\n\t\t\t}\n\t\t\treturn requiredType.cast(value);\n\t\t}\n\t\t// else\n\t\tthrow new NamespacedHierarchicalStoreException(\n\t\t\t\"Object stored under key [%s] is not of required type [%s], but was [%s]: %s\".formatted(key,\n\t\t\t\trequiredType.getName(), value.getClass().getName(), value));\n\t}\n\n\tprivate void rejectIfClosed() {\n\t\tif (this.closed) {\n\t\t\tthrow new NamespacedHierarchicalStoreException(\n\t\t\t\t\"A NamespacedHierarchicalStore cannot be modified or queried after it has been closed\");\n\t\t}\n\t}\n\n\tprivate record CompositeKey<N>(N namespace, Object key) {\n\n\t\tCompositeKey {\n\t\t\tPreconditions.notNull(namespace, \"namespace must not be null\");\n\t\t\tPreconditions.notNull(key, \"key must not be null\");\n\t\t}\n","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-platform-engine/src/main/java/org/junit/platform/engine/support/store/NamespacedHierarchicalStore.java#L475-L511","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nstore.put(Namespace.GLOBAL, \"cfg\", 42);          // Integer\nString s = store.get(Namespace.GLOBAL, \"cfg\", String.class); // throws\n// after\nInteger i = store.get(Namespace.GLOBAL, \"cfg\", Integer.class);","handlingStrategy":"type-guard","validationCode":"// Check the stored type before requesting it\nObject raw = store.get(namespace, key, Object.class);\nif (raw != null && !requiredType.isInstance(raw)) {\n    throw new IllegalStateException(\"stored type is \" + raw.getClass());\n}\nT value = store.get(namespace, key, requiredType);","typeGuard":"static <T> boolean storeHasType(NamespacedHierarchicalStore s, Namespace n, Object k, Class<T> t) {\n    Object v = s.get(n, k, Object.class);\n    return v == null || t.isInstance(v);\n}","tryCatchPattern":"try {\n    return store.get(namespace, key, requiredType);\n} catch (NamespacedHierarchicalStoreException e) {\n    // wrong type: read message, migrate the key, or use a new key\n}","preventionTips":["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."],"tags":["store","type-mismatch","extension-context","class-cast"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}