phar-io/version · error · NoBuildMetaDataException

No build metadata set

Error message

No build metadata set

What it means

NoBuildMetaDataException is thrown by Version::getBuildMetaData when the version string had no '+' build-metadata section, so hasBuildMetaData() returns false. The getter cannot return null due to its return type, so it throws instead. Build metadata is optional in SemVer, so this is an expected condition for most versions.

Solutions

  1. Check $version->hasBuildMetaData() before calling getBuildMetaData().
  2. Catch NoBuildMetaDataException and substitute null or an empty value.
  3. If metadata is required, ensure the input version string includes a '+build' segment before constructing the Version.

Example fix

// before
$meta = $version->getBuildMetaData();

// after
$meta = $version->hasBuildMetaData() ? $version->getBuildMetaData() : null;
Defensive patterns

Strategy: type-guard

Validate before calling

// PHP
if (strpos($versionString, '+') === false) {
    // no build metadata; skip metadata handling
}

Type guard

function getMetaOrNull(\Composer\Semver\Version $v): ?\Composer\Semver\BuildMetaData {
    return $v->hasBuildMetaData() ? $v->getBuildMetaData() : null;
}

Try / catch

try {
    $meta = $version->getBuildMetaData();
} catch (NoBuildMetaDataException $e) {
    $meta = null;
}

Prevention

When it happens

Trigger: Calling $version->getBuildMetaData() on a Version like '1.2.3' or '1.2.3-rc.1' (no '+metadata'); equals() internally guards with hasBuildMetaData, but direct calls do not.

Common situations: Serializing a version back to string and assuming build metadata always exists; comparing or logging build identifiers of packages installed from stable tags; test code parsing '1.0.0' and then querying metadata.

Related errors


AI-assisted analysis of phar-io/version@5eeb03f1ee (2026-09-14). Data as JSON: /api/errors/16f5558f72d15d52. Report an issue: GitHub.

Appendix: source

Thrown at src/Version.php:152

    public function getPatch(): VersionNumber {
        return $this->patch;
    }

    /**
     * @psalm-assert-if-true BuildMetaData $this->buildMetadata
     * @psalm-assert-if-true BuildMetaData $this->getBuildMetaData()
     */
    public function hasBuildMetaData(): bool {
        return $this->buildMetadata !== null;
    }

    /**
     * @throws NoBuildMetaDataException
     */
    public function getBuildMetaData(): BuildMetaData {
        if (!$this->hasBuildMetaData()) {
            throw new NoBuildMetaDataException('No build metadata set');
        }

        return $this->buildMetadata;
    }

    /**
     * @param string[] $matches
     *
     * @throws InvalidPreReleaseSuffixException
     */
    private function parseVersion(array $matches): void {
        $this->major = new VersionNumber((int)$matches['Major']);
        $this->minor = isset($matches['Minor']) ? new VersionNumber((int)$matches['Minor']) : new VersionNumber(0);
        $this->patch = isset($matches['Patch']) ? new VersionNumber((int)$matches['Patch']) : new VersionNumber(0);

        if (isset($matches['PreReleaseSuffix']) && $matches['PreReleaseSuffix'] !== '') {
            $this->preReleaseSuffix = new PreReleaseSuffix($matches['PreReleaseSuffix']);
        }

View on GitHub (pinned to 5eeb03f1ee)