getgrav/grav · error · Pimple\Exception\UnknownIdentifierException
Identifier "%s" is not defined.
Error message
Identifier "%s" is not defined.
What it means
Pimple throws UnknownIdentifierException from Container::offsetGet() when the requested string ID has never been registered. Retrieval does not create a default value; the keys map is populated only by offsetSet(), the constructor, or a service provider.
Source
Thrown at system/src/Pimple/Container.php:130
}
/**
* Gets a parameter or an object.
*
* @param string $id The unique identifier for the parameter or object
*
* @return mixed The value of the parameter or an object
*
* @throws UnknownIdentifierException If the identifier is not defined
*/
public function offsetGet(mixed $id): mixed
{
if (!is_string($id)) {
throw new InvalidServiceIdentifierException($id);
}
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}
if (
isset($this->raw[$id])
|| !is_object($this->values[$id])
|| isset($this->protected[$this->values[$id]])
|| !method_exists($this->values[$id], '__invoke')
) {
return $this->values[$id];
}
if (isset($this->factories[$this->values[$id]])) {
return $this->values[$id]($this);
}
$raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw;View on GitHub (pinned to 6040efed04)
Solutions
- Correct the service name to the exact registered string.
- Call isset($container[$id]) or in_array($id, $container->keys(), true) before dynamic access.
- Register the missing ID before it is requested.
- If using a PSR-11 ServiceLocator, ensure the ID was included in its constructor whitelist rather than assuming the full container is available.
Example fix
// before
$service = $container['assetss']; // typo, not defined
// after
$id = 'assets';
if (!isset($container[$id])) {
throw new LogicException(sprintf('Service "%s" is not registered; available: %s', $id, implode(', ', $container->keys())));
}
$service = $container[$id]; Defensive patterns
Strategy: validation
Validate before calling
if (!isset($container[$id])) {
throw new LogicException(sprintf('Service "%s" is not registered. Defined: %s', $id, implode(', ', $container->keys())));
}
$service = $container[$id]; Try / catch
try {
$service = $container[$id];
} catch (UnknownIdentifierException $e) {
if ($optional) {
return $default;
}
throw $e;
} Prevention
- Use exact service-name constants shared by producers and consumers.
- Check isset() before every dynamic service lookup.
- Do not assume third-party services are registered; make dependencies explicit.
- Assert required IDs during bootstrap rather than catching at request time.
When it happens
Trigger: Executing $container['twigg'] for a service registered as 'twig', fetching a service before its provider has registered it, or requesting an ID that only exists in a different Pimple container or ServiceLocator whitelist.
Common situations: Typos and case differences in Grav service names, a plugin expecting another plugin's service without checking availability, initialization-order bugs, or calling container code with IDs loaded from an outdated configuration file.
Related errors
- Cannot override frozen service "%s".
- Identifier "%s" does not contain an object definition.
- Service definition is not a Closure or invokable object.
- Callable is not a Closure or invokable object.
- Extension service definition is not a Closure or invokable o
AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17).
Data as JSON: /api/errors/c2be48dd70a74579.
Report an issue: GitHub.