composer/composer · error · RuntimeException

Advisory for could not be loaded as a full advisory from

Error message

Advisory for ${packageName} could not be loaded as a full advisory from ${repoName}
${data}

What it means

PackageRepository (the inline `package` repo type) can carry inline `security-advisories`. When getSecurityAdvisories() runs with allowPartialAdvisories=false, each advisory must upgrade from PartialSecurityAdvisory to a full SecurityAdvisory (i.e. have all required fields). If it cannot, the offending data is exported and thrown (src/Composer/Repository/PackageRepository.php:96-97).

Solutions

  1. Ensure every inline advisory has the full set of required fields (at minimum: packageId/affectedVersions and a link or reportedAt).
  2. Cross-check the field names against Composer's SecurityAdvisory schema.
  3. If partial advisories are acceptable in your flow, pass allowPartialAdvisories=true where the API supports it.

Example fix

// before
"security-advisories": {"vendor/pkg": [{"advisoryId": "X", "title": "RCE"}]}

// after - add affectedVersions
"security-advisories": {"vendor/pkg": [{"advisoryId": "X", "title": "RCE", "affectedVersions": ">=1.0,<1.2", "link": "https://example.com/X"}]}
Defensive patterns

Strategy: validation

Validate before calling

// Validate inline advisory entries have the fields needed for a full advisory
$required = ['advisoryId','affectedVersions'];
foreach ($advisories as $pkg => $list) {
    foreach ($list as $a) {
        foreach ($required as $r) {
            if (!isset($a[$r])) {
                throw new \UnexpectedValueException("Advisory for $pkg missing $r");
            }
        }
    }
}

Try / catch

try { $repo->getSecurityAdvisories($map, false); }
catch (\RuntimeException $e) { /* the exported $data shows which field is missing */ }

Prevention

When it happens

Trigger: Defining a `package` repository with `security-advisories` entries missing required fields (e.g. no affectedVersions, no link/title) and then running an advisory audit that disallows partial advisories.

Common situations: Hand-authoring inline advisories for testing and omitting a required field, or copy-pasting an advisory shape that worked only as partial data.

Related errors


AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07). Data as JSON: /api/errors/48fc4546a968d634. Report an issue: GitHub.

Appendix: source

Thrown at src/Composer/Repository/PackageRepository.php:97

        return Preg::replace('{^array }', 'package ', parent::getRepoName());
    }

    public function hasSecurityAdvisories(): bool
    {
        return count($this->securityAdvisories) > 0;
    }

    public function getSecurityAdvisories(array $packageConstraintMap, bool $allowPartialAdvisories = false): array
    {
        $parser = new VersionParser();

        $advisories = [];
        foreach ($this->securityAdvisories as $packageName => $packageAdvisories) {
            if (isset($packageConstraintMap[$packageName])) {
                $advisories[$packageName] = array_values(array_filter(array_map(function (array $data) use ($packageName, $allowPartialAdvisories, $packageConstraintMap, $parser) {
                    $advisory = PartialSecurityAdvisory::create($packageName, $data, $parser);
                    if (!$allowPartialAdvisories && !$advisory instanceof SecurityAdvisory) {
                        throw new \RuntimeException('Advisory for '.$packageName.' could not be loaded as a full advisory from '.$this->getRepoName() . PHP_EOL . var_export($data, true));
                    }

                    if (!$advisory->affectedVersions->matches($packageConstraintMap[$packageName])) {
                        return null;
                    }

                    return $advisory;
                }, $packageAdvisories)));
            }
        }

        return ['advisories' => array_filter($advisories, static function ($adv): bool { return \count($adv) > 0; }), 'namesFound' => array_keys($advisories)];
    }

    public function hasFilter(): bool
    {
        return count($this->filter) > 0;
    }

View on GitHub (pinned to c435d285c9)