composer/composer · error · UnexpectedValueException

Invalid ignore rule for "%s": expected an object, got %s.

Error message

Invalid ignore rule for "%s": expected an object, got %s.

What it means

Thrown by IgnorePackageRule::parseIgnoreMap() when iterating a list-of-rules value (e.g. `"vendor/pkg": [{...}, {...}]`) and one of the elements is not an array. Each element of the list must be a rule object (associative array with constraint/reason/on-block/on-audit keys); non-array elements are rejected.

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 6ffc117740)

Solutions

  1. Make every element of the list an object: `ignore: { 'vendor/pkg': [{ 'constraint': '^1.0' }, { 'constraint': '^3.0' }] }`.
  2. For a single reason string, use the direct form: `ignore: { 'vendor/pkg': 'reason text' }` (no list wrapper).
  3. For one rule with options, use a single object, not a list: `ignore: { 'vendor/pkg': { 'constraint': '^1.0', 'reason': '...' } }`.

Example fix

// before
['ignore' => ['vendor/pkg' => ['legacy reason', ['constraint' => '^1.0']]]]

// after
['ignore' => ['vendor/pkg' => [['constraint' => '^1.0', 'reason' => 'legacy']]]]
Defensive patterns

Strategy: validation

Validate before calling

function ignoreListEntriesAreObjects(array $listValue): bool {
    foreach ($listValue as $entry) {
        if (!is_array($entry) || array_is_list($entry) && count($entry) === 0) {
            // a rule object is associative; reject sequential arrays and non-arrays
            if (!is_array($entry)) {
                return false;
            }
        }
    }
    return true;
}

Type guard

function isIgnoreRuleObject($value): bool {
    return is_array($value)
        && (isset($value['constraint']) || isset($value['reason']) || isset($value['on-block']) || isset($value['on-audit']));
}

Prevention

When it happens

Trigger: Config like `ignore: { 'vendor/pkg': ['reason', { 'constraint': '^1.0' }] }` where one list element is a string rather than an object. Reached at IgnorePackageRule.php:110 inside the `is_array($value) && isset($value[0])` branch when is_array($ruleConfig) is false for some element.

Common situations: Mixing the simple-string reason form with the list-of-objects form; YAML flow style merges values; user assumes positional strings are allowed in the list (they are not — strings belong as the direct value, not inside the list).

Related errors


AI-assisted analysis of composer/composer@6ffc117740 (2026-08-07). Data as JSON: /api/errors/0d6e5c1743f794f8. Report an issue: GitHub.