{"record":{"id":"a639e9a7d4d7bc12","repo":"junit-team/junit5","slug":"failed-to-inject-parameter-value-into-field-s","errorCode":null,"errorMessage":"Failed to inject parameter value into field: %s","messagePattern":"Failed to inject parameter value into field: (.+?)","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolverFacade.java","lineNumber":313,"sourceCode":"\t\t\t\t\t\tinvocationIndex, resolutionCache));\n\t\t}\n\t}\n\n\tprivate Stream<ParameterDeclaration> getAllParameterDeclarations() {\n\t\treturn Stream.concat(this.indexedParameterDeclarations.declarationsByIndex.values().stream(),\n\t\t\taggregatorParameters.stream());\n\t}\n\n\tprivate void setField(Object testInstance, FieldParameterDeclaration declaration, ExtensionContext extensionContext,\n\t\t\tEvaluatedArgumentSet arguments, int invocationIndex, ResolutionCache resolutionCache) {\n\n\t\tObject argument = resolutionCache.resolve(declaration,\n\t\t\t() -> resolve(declaration, extensionContext, arguments, invocationIndex, Optional.empty()));\n\t\ttry {\n\t\t\tdeclaration.getField().set(testInstance, argument);\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new JUnitException(\"Failed to inject parameter value into field: \" + declaration.getField(), e);\n\t\t}\n\t}\n\n\tprivate @Nullable Object resolve(ResolvableParameterDeclaration parameterDeclaration,\n\t\t\tExtensionContext extensionContext, EvaluatedArgumentSet arguments, int invocationIndex,\n\t\t\tOptional<ParameterContext> parameterContext) {\n\t\tResolver resolver = getResolver(extensionContext, parameterDeclaration);\n\t\treturn parameterDeclaration.resolve(resolver, extensionContext, arguments, invocationIndex, parameterContext);\n\t}\n\n\tprivate Resolver getResolver(ExtensionContext extensionContext, ResolvableParameterDeclaration declaration) {\n\t\treturn this.resolvers.computeIfAbsent(declaration, __ -> this.aggregatorParameters.contains(declaration) //\n\t\t\t\t? createAggregator(declaration, extensionContext) //\n\t\t\t\t: createConverter(declaration, extensionContext));\n\t}\n\n\tprivate int toLogicalIndex(ParameterContext parameterContext) {\n\t\tint index = parameterContext.getIndex() - this.parameterIndexOffset;","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/ResolverFacade.java#L295-L331","documentation":"Thrown by ResolverFacade.setField() when Field.set() fails during injection of a resolved parameter value into a @Parameter-annotated field of a @ParameterizedClass test instance. The underlying exception (typically IllegalAccessException due to final fields, type mismatch, or security manager restrictions) is attached as the cause. The %s placeholder is the Field's toString() representation including declaring class and field name.","triggerScenarios":"A @Parameter-annotated field is declared final, making Field.set() fail. A @Parameter field's declared type doesn't match the resolved argument type and auto boxing/unboxing can't bridge it. The field belongs to a class loaded by a different class loader with restrictive access. A security manager blocks reflective field access on JDK 17+ without --add-opens.","commonSituations":"Using @Parameter on a final field (common in record-style or immutable test classes). JDK 16+ strong encapsulation where reflective access to private fields of JDK classes or modules is denied. Kotlin test classes where fields have different accessibility semantics than expected by Java reflection.","solutions":["Remove the 'final' modifier from @Parameter-annotated fields — JUnit needs to write to them","Ensure the field's type is compatible with the argument source's value type (or add an ArgumentConverter)","On JDK 16+, add --add-opens flags to the JVM if accessing fields across module boundaries","Make the field accessible (public) or ensure the test class is open for reflection (Kotlin: use @Open or the kotlin-spring plugin)"],"exampleFix":"// before — final field blocks injection\n@ParameterizedClass\nclass MyTest {\n    @Parameter\n    private final int value;\n}\n\n// after — remove final\n@ParameterizedClass\nclass MyTest {\n    @Parameter\n    private int value;\n}","handlingStrategy":"validation","validationCode":"// Validate that @Parameter fields are not final and are accessible\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\n\nstatic void validateParameterFields(Class<?> testClass) {\n    for (Field f : testClass.getDeclaredFields()) {\n        if (f.isAnnotationPresent(org.junit.jupiter.params.Parameter.class)) {\n            if (Modifier.isFinal(f.getModifiers())) {\n                throw new IllegalStateException(\n                    \"@Parameter field \" + f.getName() + \" must not be final\");\n            }\n            f.setAccessible(true); // ensure access on JDK 16+\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never declare @Parameter fields as final — JUnit needs to write to them via reflection","Ensure @Parameter field types are compatible with the argument source values or use @ConvertWith","On JDK 16+, add appropriate --add-opens JVM arguments if the test class is in a restricted module"],"tags":["field-injection","reflection","parameterized-class","junit-params"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}