apache/maven · error · DIException
No binding to construct an instance for key {}. Existing bi
Error message
No binding to construct an instance for key {}. Existing bindings:
- {} What it means
A dependency-injection failure from the Sisu-to-consumer-API bridge: code asked the DI container for a component at a given key (type plus qualifier), no Plexus/Sisu bean matched, and the injection point was not optional. The message helpfully lists every key that IS bound, so you can see what the container knows about versus what you requested.
Source
Thrown at impl/maven-core/src/main/java/org/apache/maven/internal/impl/SisuDiBridgeModule.java:196
private <Q> Supplier<Q> getBeanSupplier(Dependency<Q> dep, Key<Q> key) {
List<Binding<?>> list = new ArrayList<>();
// Add DI bindings
list.addAll(getBindings().getOrDefault(key, Set.of()));
// Add Plexus bindings
for (var bean : locator.get().locate(toGuiceKey(key))) {
if (isPlexusBean(bean)) {
list.add(new BindingToBeanEntry<>(key).toBeanEntry(bean).prioritize(bean.getRank()));
}
}
if (!list.isEmpty()) {
list.sort(getPriorityComparator());
//noinspection unchecked
return () -> (Q) getInstance(list.iterator().next());
} else if (dep.optional()) {
return () -> null;
} else {
throw new DIException("No binding to construct an instance for key "
+ key.getDisplayString() + ". Existing bindings:\n"
+ getBoundKeys().stream()
.map(Key::toString)
.map(String::trim)
.sorted()
.distinct()
.collect(Collectors.joining("\n - ", " - ", "")));
}
}
@Override
public <T> Set<Binding<T>> getAllBindings(Class<T> clazz) {
Key<T> key = Key.of(clazz);
Set<Binding<T>> bindings = new HashSet<>();
Set<Binding<T>> diBindings = super.getBindings(key);
if (diBindings != null) {
bindings.addAll(diBindings);
}View on GitHub (pinned to e4093d4e12)
Solutions
- Compare your requested key with the 'Existing bindings' list printed in the message — usually the type or qualifier is spelled differently
- Add the dependency that contains the default implementation of the service (e.g. maven-core's impl artifact) to your plugin/embedder classpath
- If you wrote the component, annotate it with @Named/@Singleton and ensure META-INF/sisitu index generation runs (sisu-maven-plugin)
- For optional lookups, use the API variant that supports optional dependencies instead of a hard lookup
Example fix
// before WorkspaceReader reader = session.getService(WorkspaceReader.class); // DIException: no binding // after // add the artifact that provides the default component, e.g. in plugin dependencies: <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-core</artifactId> <scope>provided</scope> </dependency>
Defensive patterns
Strategy: validation
Validate before calling
// before a hard service lookup, verify a binding exists
try {
T service = session.getService(type); // throws DIException if unbound
} catch (DIException e) {
LOG.warn("Service not available: {}", type.getName());
} Try / catch
catch (org.apache.maven.api.di.DiException | org.eclipse.sisu.InjectionException e) {
// inspect message: 'Existing bindings' list tells you what the container offers
throw new IllegalStateException("Missing DI binding for " + type, e);
} Prevention
- Depend on the artifacts that provide default service implementations (maven-core impl) with provided scope
- Prefer constructor injection over manual getService lookups — wiring problems surface at startup
- When requesting qualified components, double-check @Named strings against the provider
When it happens
Trigger: Calling session.getService(SomeService.class) (or injecting a qualified component) where no implementation of SomeService is registered; requesting a @Named-qualified component whose qualifier string does not match any @Named annotation on implementations; a plugin missing a META-INF/sisitu/javax.inject.Named file so its components are never indexed.
Common situations: Using a maven-api service interface inside a plugin without depending on the module that provides its default implementation; upgrading Maven where a service moved packages or got renamed; classpath shading or duplicate plugin jars hiding the component; qualifier typo such as @Named("mvn") vs @Named("maven").
Related errors
- Cannot read metadata from '{}'
- Unable to lookup org.eclipse.aether.RepositorySystem
- Only String keys are supported for maps: {}
- Error in component graph of plugin ${plugin.getId()}: ${e.ge
- Unable to load the mojo '${mojoDescriptor.getGoal()}' (or on
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/6d81e9f0bd31bc1d.
Report an issue: GitHub.