phalcon/cphalcon · error · Phalcon\Mvc\Router\Exceptions\ConfigKeyMustBeArray
'defaults' must be an array
Error message
'defaults' must be an array
What it means
Inside loadFromConfig(), the optional 'defaults' key sets router defaults via setDefaults(), which requires an array (e.g. ['module' => 'frontend', 'controller' => 'index']). If config['defaults'] exists but is a scalar, string, or object, the router throws ConfigKeyMustBeArray('defaults') naming the offending key.
Source
Thrown at phalcon/Mvc/Router.zep:1768
if !(config instanceof ConfigInterface) {
throw new InvalidConfigSource();
}
let config = config->toArray();
}
if typeof config !== "array" {
throw new InvalidConfigSource();
}
if isset config["removeExtraSlashes"] {
let removeExtra = config["removeExtraSlashes"];
this->removeExtraSlashes((bool) removeExtra);
}
if isset config["defaults"] {
let defaults = config["defaults"];
if typeof defaults !== "array" {
throw new ConfigKeyMustBeArray("defaults");
}
this->setDefaults(defaults);
}
if fetch routes, config["routes"] {
if typeof routes !== "array" {
throw new ConfigKeyMustBeArray("routes");
}
for routeData in routes {
this->addRouteFromConfig(routeData);
}
}
if fetch groups, config["groups"] {
if typeof groups !== "array" {
throw new ConfigKeyMustBeArray("groups");
}
for groupData in groups {View on GitHub (pinned to b7419de9cd)
Solutions
- Make 'defaults' an array: "defaults": {"module": "frontend", "controller": "index", "action": "index"}
- If decoding JSON, pass true: json_decode($json, true) so nested objects become arrays
- Validate the shape before loading (see validation snippet) so the failure names the file, not the router
Example fix
// before
$config = json_decode(file_get_contents('routes.json'));
// {"defaults": "frontend"} -> stdClass/string defaults
$router->loadFromConfig($config);
// after
$config = json_decode(file_get_contents('routes.json'), true);
// {"defaults": {"module": "frontend", "controller": "index"}}
$router->loadFromConfig($config); Defensive patterns
Strategy: validation
Validate before calling
// validate the whole router-config shape before handing it to the router
function validateRouterConfig(array $config): void
{
if (isset($config['defaults']) && !is_array($config['defaults'])) {
throw new InvalidArgumentException("'defaults' must be an array");
}
if (isset($config['routes']) && !is_array($config['routes'])) {
throw new InvalidArgumentException("'routes' must be an array");
}
if (isset($config['groups']) && !is_array($config['groups'])) {
throw new InvalidArgumentException("'groups' must be an array");
}
}
validateRouterConfig($config);
$router->loadFromConfig($config); Type guard
function defaultsAreValid(array $config): bool
{
return !isset($config['defaults']) || is_array($config['defaults']);
} Try / catch
try {
$router->loadFromConfig($config);
} catch (\Phalcon\Mvc\Router\Exceptions\ConfigKeyMustBeArray $e) {
// message names the offending key, e.g. "'defaults' must be an array"
$logger->error('Router config key invalid: ' . $e->getMessage());
throw $e;
} Prevention
- Always call json_decode($json, true) for route configs so nested objects become arrays
- Keep a JSON schema for your routes file and validate it in CI
- Write 'defaults' as a map of module/controller/action, never a scalar
When it happens
Trigger: A config file containing "defaults": "frontend" or "defaults": {"module": "frontend"} decoded to an object (json_decode without true) instead of an array; a YAML defaults scalar.
Common situations: json_decode() without the $associative flag turning every nested object into stdClass; hand-edited YAML using a scalar where a map was intended; defaults written as a single string module name.
Understand the failure class
Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.
Related errors
- loadFromConfig requires an array or Phalcon\Config\ConfigInt
- 'routes' must be an array
- 'groups' must be an array
- Route config entry is missing 'pattern'
- Route config entry is missing 'paths'
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/b4e415fd00f2fbcd.
Report an issue: GitHub.