composer/composer · error · UnexpectedValueException
Invalid ignore rule for
Error message
Invalid ignore rule for "%s": expected an object, got %s.
What it means
Thrown by IgnorePackageRule::parseIgnoreMap() when a package key maps to a list of rule objects but one of the list elements is not an array. Each element of a list-valued ignore entry must itself be a rule-object array (with keys like constraint/reason/on-block); a non-array element (string, int, null) is rejected because it cannot be parsed into an IgnorePackageRule.
Solutions
- Ensure every element of a list-valued ignore entry is a rule-object array, e.g. {"vendor/pkg": [{"constraint": "^1.0"}, {"constraint": "^3.0", "on-block": false}]}.
- If you only need a single rule with no version constraint, use the string-reason or null form instead of a list: {"vendor/pkg": "reason"} or {"vendor/pkg": null}.
- Validate the list before parsing: each element of a list-valued entry must be an array.
- Check YAML/JSON indentation to ensure list items are objects, not scalars.
Example fix
// before
{"ignore": {"vendor/pkg": [{"constraint": "^1.0"}, "legacy"]}}
// second list element is a string -> throws
// after
{"ignore": {"vendor/pkg": [{"constraint": "^1.0"}, {"constraint": "^2.0", "reason": "legacy"}]}} Defensive patterns
Strategy: validation
Validate before calling
// Validate list-valued ignore entries before parsing.
foreach ($config as $key => $value) {
if (is_array($value) && !is_int($key) && isset($value[0])) {
foreach ($value as $i => $ruleConfig) {
if (!is_array($ruleConfig)) {
throw new \UnexpectedValueException("ignore[$key][$i] must be a rule object");
}
}
}
}
$rules = \Composer\Policy\IgnorePackageRule::parseIgnoreMap($config); Type guard
/** @param mixed $ruleConfig */
function isRuleObject($ruleConfig): bool {
return is_array($ruleConfig);
} Try / catch
try {
$rules = IgnorePackageRule::parseIgnoreMap($config);
} catch (\UnexpectedValueException $e) {
// a list element wasn't an object - convert to {"constraint":...} shape
} Prevention
- Each element of a list-valued ignore entry must be a rule-object array.
- For single unversioned ignores, use the string-reason or null form instead of a list.
- Check YAML/JSON indentation so list items remain objects, not scalars.
When it happens
Trigger: parseIgnoreMap() reaches the list-of-rules branch (line 107: is_array($value) && isset($value[0])) and iterates $value; if any $ruleConfig is not an array, line 109-115 throws with the key and get_debug_type() of the offending element. E.g. {"vendor/pkg": [{"constraint": "^1.0"}, "reason"]} - second element is a string.
Common situations: Mixing a rule-object list with stray scalar entries; a YAML list where an item collapsed to a scalar; copy-paste merging a string reason into a list of objects; an inconsistent config where some entries are objects and one is a bare string.
Related errors
- Invalid ignore-id entry at index
- Invalid ignore-id entry for
- " " is an invalid value for , must be one of: ignore…
- --abandoned must be one of
- At least one scope is required.
AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07).
Data as JSON: /api/errors/0d6e5c1743f794f8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Composer/Policy/IgnorePackageRule.php:110
}
// Simple string reason: "vendor/pkg": "reason"
if (is_string($value) && !is_int($key)) {
$rules[$key][] = new self($key, new MatchAllConstraint(), $value);
continue;
}
// Numeric key with string value: ["vendor/pkg"]
if (is_int($key) && is_string($value)) {
$rules[$value][] = new self($value, new MatchAllConstraint());
continue;
}
// Array of rule objects: "vendor/pkg": [{...}, {...}]
if (is_array($value) && !is_int($key) && isset($value[0])) {
foreach ($value as $ruleConfig) {
if (!is_array($ruleConfig)) {
throw new \UnexpectedValueException(sprintf(
'Invalid ignore rule for "%s": expected an object, got %s.',
$key,
get_debug_type($ruleConfig)
));
}
$rules[$key][] = self::fromRuleObject($key, $ruleConfig, $parser);
}
continue;
}
// Single rule object: "vendor/pkg": {"constraint": "...", ...}
if (is_array($value) && !is_int($key)) {
$rules[$key][] = self::fromRuleObject($key, $value, $parser);
continue;
}
throw new \UnexpectedValueException(sprintf(
'Invalid ignore entry at key "%s": value of type %s is not a supported shape.'View on GitHub (pinned to c435d285c9)