Composer "replace"/"provide" Conflict - Phantom or Duplicate Packages
A replace entry tells Composer a package is already provided (so it should not be installed separately), and provide declares a virtual capability is satisfied. When these are set wrong - a stale replace, or a provide with no real implementation - resolution either omits a package you need or cannot find a concrete provider.
What this error means
Composer resolves to a set that is missing a package you expected (because something replaces it), or fails to resolve a virtual requirement that only has provide declarations and no real implementation. The class/function from the "replaced" package is absent at runtime.
// a monorepo package replaces a split package it no longer ships
"replace": { "acme/logger": "*" }
# Composer therefore never installs acme/logger, but app code still uses it:
PHP Fatal error: Uncaught Error: Class "Acme\Logger\Logger" not foundCommon causes
A stale or wildcard replace hides a real package
"replace": { "acme/logger": "*" } claims this package supplies acme/logger, so Composer skips installing the real one. If it no longer actually ships those classes, they vanish.
A provide with no concrete implementation
A provide for a virtual package (e.g. psr/log-implementation) satisfies a requirement on paper. If nothing real implements it, code that resolves the implementation at runtime fails.
How to fix it
Find what replaces or provides the missing package
Ask Composer why a package is absent or how a virtual requirement is satisfied.
composer why-not acme/logger
composer depends acme/logger
composer show --tree | grep -i loggerRemove the stale replace entry
If a replace no longer reflects reality, drop it so Composer installs the real package again.
{
"replace": {}
}Require a concrete implementation for a virtual package
When a provide is virtual, also require something that really implements it.
composer require monolog/monolog # real psr/log implementationHow to prevent it
- Use
replaceonly for code you actually bundle; avoid wildcard versions. - Pair every virtual
providewith a real implementing dependency. - Run
composer show --treeto verify the resolved set contains what you expect.