{"record":{"id":"080d945e97b86419","repo":"junit-team/junit5","slug":"no-parameterresolver-registered-for-parameter-s","errorCode":null,"errorMessage":"No ParameterResolver registered for parameter [%s] in %s [%s].","messagePattern":"No ParameterResolver registered for parameter \\[(.+?)\\] in (.+?) \\[(.+?)\\]\\.","errorType":"exception","errorClass":"ParameterResolutionException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/ParameterResolutionUtils.java","lineNumber":134,"sourceCode":"\t\tfor (int i = start; i < parameters.length; i++) {\n\t\t\tParameterContext parameterContext = new DefaultParameterContext(parameters[i], i, target);\n\t\t\tvalues[i] = resolveParameter(parameterContext, executable, extensionContext, extensionRegistry);\n\t\t}\n\t\treturn values;\n\t}\n\n\tprivate static @Nullable Object resolveParameter(ParameterContext parameterContext, Executable executable,\n\t\t\tExtensionContextSupplier extensionContext, ExtensionRegistry extensionRegistry) {\n\n\t\ttry {\n\t\t\t// @formatter:off\n\t\t\tList<ParameterResolver> matchingResolvers = extensionRegistry.stream(ParameterResolver.class)\n\t\t\t\t\t.filter(resolver -> resolver.supportsParameter(parameterContext, extensionContext.get(resolver)))\n\t\t\t\t\t.toList();\n\t\t\t// @formatter:on\n\n\t\t\tif (matchingResolvers.isEmpty()) {\n\t\t\t\tthrow new ParameterResolutionException(\n\t\t\t\t\t\"No ParameterResolver registered for parameter [%s] in %s [%s].\".formatted(\n\t\t\t\t\t\tparameterContext.getParameter(), asLabel(executable), executable.toGenericString()));\n\t\t\t}\n\n\t\t\tif (matchingResolvers.size() > 1) {\n\t\t\t\t// @formatter:off\n\t\t\t\tString resolvers = matchingResolvers.stream()\n\t\t\t\t\t\t.map(StringUtils::defaultToString)\n\t\t\t\t\t\t.collect(joining(\", \"));\n\t\t\t\t// @formatter:on\n\t\t\t\tthrow new ParameterResolutionException(\n\t\t\t\t\t\"Discovered multiple competing ParameterResolvers for parameter [%s] in %s [%s]: %s\".formatted(\n\t\t\t\t\t\tparameterContext.getParameter(), asLabel(executable), executable.toGenericString(), resolvers));\n\t\t\t}\n\n\t\t\tParameterResolver resolver = matchingResolvers.get(0);\n\t\t\tObject value = resolver.resolveParameter(parameterContext, extensionContext.get(resolver));\n\t\t\tvalidateResolvedType(parameterContext.getParameter(), value, executable, resolver);","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/junit-team/junit5/blob/f070c699a08b5d8393df9afd147af5c5e90bb21b/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/execution/ParameterResolutionUtils.java#L116-L152","documentation":"Thrown as ParameterResolutionException when no registered ParameterResolver reports supportsParameter(...) == true for a parameter of a test constructor or test/lifecycle method. JUnit Jupiter resolves every parameter via extensions, so an unresolved parameter is fatal for that invocation.","triggerScenarios":"resolveParameter filters the extensionRegistry stream of ParameterResolver to those that supportsParameter; if matchingResolvers.isEmpty(), the throw fires. Common with constructor/method parameters that no built-in or registered resolver handles (TestInfo, RepetitionInfo, TestReporter are built-in; arbitrary types need an extension).","commonSituations":"Asking for a domain object (UserService, RestClient) without a corresponding ParameterResolver; typo in a custom resolver's supportsParameter; a resolver that only handles certain parameter names/positions; using a parameter type supported only when an annotation is present but the annotation was forgotten.","solutions":["Add @RegisterExtension/@ExtendWith for a ParameterResolver that handles the unresolved type.","Switch the parameter to a built-in resolvable type (TestInfo, TestReporter, RepetitionInfo, ExtensionContext, TempDir) and read what you need from it.","Fix a custom resolver's supportsParameter to return true for the relevant parameter context (check annotations, position, declaring executable)."],"exampleFix":"// before\n@Test\nvoid uses(UserService svc) { } // no resolver\n// after - register a resolver that builds it\n@RegisterExtension\nstatic final UserServiceResolver resolver = new UserServiceResolver();\n\nstatic class UserServiceResolver implements ParameterResolver {\n    @Override public boolean supportsParameter(ParameterContext pc, ExtensionContext ec) {\n        return pc.getParameter().getType() == UserService.class;\n    }\n    @Override public Object resolveParameter(ParameterContext pc, ExtensionContext ec) {\n        return new UserService();\n    }\n}","handlingStrategy":"validation","validationCode":"List<ParameterResolver> resolvers = ServiceLoader.load(ParameterResolver.class).stream()\n    .map(p -> p.get())\n    .filter(r -> r.supportsParameter(parameterContext, extensionContext))\n    .toList();\nif (resolvers.isEmpty()) {\n    throw new IllegalStateException(\"No resolver for parameter \" + parameterContext.getParameter());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register a ParameterResolver for every non-builtin parameter type you inject.","Use built-in types (TestInfo, TestReporter, ExtensionContext, TempDir) where possible.","Double-check a custom resolver's supportsParameter covers the parameter context you expect."],"tags":["parameter-resolution","parameter-resolver","extension","constructor"],"backgroundTag":null,"analyzedSha":"f070c699a08b5d8393df9afd147af5c5e90bb21b","analyzedAt":"2026-08-11T20:31:00.530Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}