phar-io/manifest · error · ManifestDocumentException
Not a phar.io manifest document
Error message
Not a phar.io manifest document
What it means
ManifestDocument::ensureCorrectDocumentType validates that the parsed document's root element has localName 'phar' and the expected phar.io namespace (self::XMLNS). If not, it throws ManifestDocumentException('Not a phar.io manifest document'). The XML may be perfectly well-formed — it just isn't a phar.io manifest.
Solutions
- Check the file being loaded is actually a phar.io manifest XML
- Ensure the root element is <phar xmlns="https://phar.io/manifest"> (the library's expected XMLNS)
- Regenerate the manifest with the original build tool instead of hand-editing
- Inspect the root element: $dom->documentElement->localName / namespaceURI
Example fix
// before (manifest.xml) <manifest>...</manifest> // after <phar xmlns="https://phar.io/manifest">...</phar>
Defensive patterns
Strategy: validation
Validate before calling
$dom = new DOMDocument(); $dom->loadXML($xml); $root = $dom->documentElement; if ($root->localName !== 'phar' || $root->namespaceURI !== 'https://phar.io/manifest') { throw new RuntimeException('Not a phar.io manifest'); } Type guard
function isPharManifest(DOMDocument $dom): bool { $r = $dom->documentElement; return $r !== null && $r->localName === 'phar' && $r->namespaceURI === 'https://phar.io/manifest'; } Try / catch
try { $doc = ManifestDocument::fromFile($path); } catch (ManifestDocumentException $e) { if (str_contains($e->getMessage(), 'Not a phar.io manifest')) { /* wrong file type handling */ } throw $e; } Prevention
- Confirm you are loading the phar manifest, not another XML/config file
- Keep xmlns="https://phar.io/manifest" on the root <phar> element
- Regenerate manifests with the official tool rather than hand-editing
When it happens
Trigger: Calling ManifestDocument::fromString()/fromFile() on XML whose root element is not <phar> in the phar.io namespace — e.g. wrong root name, missing xmlns, or a completely different XML file (composer.json-style XML, arbitrary config).
Common situations: Pointing phar.io tooling (e.g. phpab, phive) at the wrong file; a manifest saved without the xmlns="https://phar.io/..." attribute; hand-edited manifest with renamed root element.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
AI-assisted analysis of phar-io/manifest@c581d4941e (2026-09-14).
Data as JSON: /api/errors/ad141b80570b4c7b.
Report an issue: GitHub.
Appendix: source
Thrown at src/xml/ManifestDocument.php:100
$this->fetchElementByName('requires')
);
}
public function hasBundlesElement(): bool {
return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1;
}
public function getBundlesElement(): BundlesElement {
return new BundlesElement(
$this->fetchElementByName('bundles')
);
}
private function ensureCorrectDocumentType(DOMDocument $dom): void {
$root = $dom->documentElement;
if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) {
throw new ManifestDocumentException('Not a phar.io manifest document');
}
}
private function fetchElementByName(string $elementName): DOMElement {
$element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0);
if (!$element instanceof DOMElement) {
throw new ManifestDocumentException(
sprintf('Element %s missing', $elementName)
);
}
return $element;
}
}
View on GitHub (pinned to c581d4941e)