phalcon/cphalcon · error · Phalcon\Container\Exceptions\ServiceNotFound
Service '{name}' not found
Error message
Service '{name}' not found What it means
Thrown by Container::extend() when the service name (after alias resolution) has no entry in the container's service map. extend() attaches a decorator callable that runs after a service is built, and it only works on names already registered with set(); unlike get(), it never autowires or lazily registers a class name. Hitting this means the decoration target does not exist at the time extend() is called.
Source
Thrown at phalcon/Container/Container.zep:170
* Extends the definition
*
* @param string $name
* @param callable $callable
*
* @return void
* @throws CannotExtendResolved
* @throws ServiceNotFound
*/
public function extend(string name, callable callableObject) -> void
{
let name = this->resolveAlias(name);
if (array_key_exists(name, this->instances)) {
throw new CannotExtendResolved(name);
}
if (!array_key_exists(name, this->services)) {
throw new ServiceNotFound(name);
}
this->services[name]->addExtender(callableObject);
}
/**
* Resolve and return an element registerd in the container
*
* @param string $name
*
* @return mixed
* @throws ServiceNotFound
*/
public function get(string name) -> mixed
{
let name = this->resolveAlias(name);
if (array_key_exists(name, this->parameters)) {View on GitHub (pinned to b7419de9cd)
Solutions
- Register the service first: $container->set('logger', Logger::class) (or load the ServiceProvider that registers it) before calling extend()
- Guard the call: if ($container->hasDefinition('logger')) { $container->extend('logger', $fn); }
- Verify the exact name — extend() resolves aliases internally, so the alias target must be a registered service name
- If your intent was to decorate an already-built object, register that object with set() instead of extending a definition
Example fix
// before
$container->extend('logger', fn ($l) => $l->pushHandler($handler)); // ServiceNotFound
// after
$container->set('logger', Logger::class);
$container->extend('logger', fn ($l, $c) => $l->pushHandler($handler)); Defensive patterns
Strategy: validation
Validate before calling
if ($container->hasDefinition('logger')) {
$container->extend('logger', fn ($logger, $c) => $logger->pushHandler($handler));
} else {
throw new LogicException("Cannot extend 'logger': service is not registered.");
} Try / catch
use Phalcon\Container\Exceptions\ServiceNotFound;
try {
$container->extend('logger', $decorator);
} catch (ServiceNotFound $e) {
// register then retry once, or fail with context
$container->set('logger', Logger::class);
$container->extend('logger', $decorator);
} Prevention
- Register every service before extending it; treat extend() as post-registration decoration only
- Centralize service names in constants to avoid typo drift between set() and extend()
- In providers, extend services at registration time, not lazily after resolution (that risks CannotExtendResolved)
When it happens
Trigger: Calling $container->extend('logger', fn ($logger, $container) => ...) when 'logger' was never passed to set() or registered by a ServiceProvider; passing an alias whose resolved target is not registered; extending before the provider that registers the service has been loaded into the container.
Common situations: Provider ordering during bootstrap (extending in provider A a service registered in provider B that runs later), migrating from Phalcon\Di\DI where service names differ, assuming extend() lazily creates the service like get() does with autowire, or a simple typo in the service name.
Related errors
- Cannot extend already-resolved service '{name}'
- Instance '{name}' not found
- Parameter '{name}' not found
- Service '{name}' not registered
- Circular alias detected: '{alias}'
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/38fbf8af04df6ef7.
Report an issue: GitHub.