PHPOffice/PHPWord · error · PhpOffice\PhpWord\Exception\Exception
No PhpWord assigned.
Error message
No PhpWord assigned.
What it means
EPub3 Part\Content::write() serializes package metadata that requires the PhpWord document. If the phpWord property is still null at write time (part written standalone or writer constructed without a document), the part refuses to produce content and throws.
Solutions
- Set the document on the part via setPhpWord($phpWord) before calling write().
- Use the normal EPub3 writer flow (IOFactory::createWriter($phpWord, 'EPub3')) which assigns parts automatically.
- Ensure the PhpWord instance passed is not null at call time.
- In custom pipelines, assert the part is fully configured before writing.
Example fix
// before $part = new \PhpOffice\PhpWord\Writer\EPub3\Part\Content(); $xml = $part->write(); // No PhpWord assigned // after $part = new \PhpOffice\PhpWord\Writer\EPub3\Part\Content(); $part->setPhpWord(new \PhpOffice\PhpWord\PhpWord()); $xml = $part->write();
Defensive patterns
Strategy: type-guard
Validate before calling
function partIsWritable(\PhpOffice\PhpWord\Writer\EPub3\Part\Content $part): bool {
$ref = new ReflectionProperty(get_class($part), 'phpWord');
$ref->setAccessible(true);
return $ref->getValue($part) !== null;
} Try / catch
try {
$xml = $part->write();
} catch (\PhpOffice\PhpWord\Exception\Exception $e) {
if ($e->getMessage() === 'No PhpWord assigned.') {
$part->setPhpWord($phpWord);
$xml = $part->write();
} else { throw $e; }
} Prevention
- Do not instantiate EPub3 parts directly; let the EPub3 writer wire them.
- Always call setPhpWord() immediately after manual part construction.
- Assert the document is set in custom writer pipelines before write().
- Cover part usage in tests that run against a real PhpWord instance.
When it happens
Trigger: Instantiating the Content part directly and calling write() without setting phpWord; using the EPub3 writer without a document; custom pipelines that build parts manually and skip setPhpWord().
Common situations: Unit tests or custom writers instantiating Part\Content in isolation; forgetting setPhpWord() after manual construction; refactored code paths that bypass the standard writer flow.
Related errors
- No PhpWord assigned.
- Invalid part type
- No parent WriterInterface assigned.
- " " is not a valid writer.
- Directory does not exist: $directory
AI-assisted analysis of PHPOffice/PHPWord@aef95c0415 (2026-09-14).
Data as JSON: /api/errors/78c64f0edfdb8480.
Report an issue: GitHub.
Appendix: source
Thrown at src/PhpWord/Writer/EPub3/Part/Content.php:65
*
* @return XMLWriter
*/
protected function getXmlWriter()
{
$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', 'UTF-8');
return $xmlWriter;
}
/**
* Write part content.
*/
public function write(): string
{
if ($this->phpWord === null) {
throw new Exception('No PhpWord assigned.');
}
$xmlWriter = $this->getXmlWriter();
$docInfo = $this->phpWord->getDocInfo();
// Write package
$xmlWriter->startElement('package');
$xmlWriter->writeAttribute('xmlns', 'http://www.idpf.org/2007/opf');
$xmlWriter->writeAttribute('version', '3.0');
$xmlWriter->writeAttribute('unique-identifier', 'book-id');
$xmlWriter->writeAttribute('xml:lang', 'en');
// Write metadata
$xmlWriter->startElement('metadata');
$xmlWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
$xmlWriter->writeAttribute('xmlns:opf', 'http://www.idpf.org/2007/opf');
// Required elementsView on GitHub (pinned to aef95c0415)