{"record":{"id":"1dc29370b9905cf2","repo":"sebastianbergmann/phpunit","slug":"could-not-parse-xml-from-empty-string","errorCode":null,"errorMessage":"Could not parse XML from empty string","messagePattern":"Could not parse XML from empty string","errorType":"exception","errorClass":"PHPUnit\\Util\\Xml\\XmlException","httpStatus":null,"severity":"error","filePath":"src/Util/Xml/Loader.php","lineNumber":68,"sourceCode":"        if (trim($contents) === '') {\n            throw new XmlException(\n                sprintf(\n                    'Could not parse XML from empty file \"%s\"',\n                    $filename,\n                ),\n            );\n        }\n\n        return $this->load($contents, $ignoreComments);\n    }\n\n    /**\n     * @throws XmlException\n     */\n    public function load(string $actual, bool $ignoreComments = false): DOMDocument\n    {\n        if ($actual === '') {\n            throw new XmlException('Could not parse XML from empty string');\n        }\n\n        $document                     = new DOMDocument;\n        $document->preserveWhiteSpace = false;\n\n        $internal  = libxml_use_internal_errors(true);\n        $message   = '';\n        $reporting = error_reporting(0);\n        $loaded    = $document->loadXML($actual, LIBXML_NONET);\n\n        foreach (libxml_get_errors() as $error) {\n            $message .= \"\\n\" . $error->message;\n        }\n\n        libxml_use_internal_errors($internal);\n        error_reporting($reporting);\n\n        if ($loaded === false) {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Util/Xml/Loader.php#L50-L86","documentation":"Xml\\Loader::load() parses an XML string (not a file) into a DOMDocument. An empty input string is rejected immediately with XmlException('Could not parse XML from empty string'), before DOMDocument ever sees it. This is the programmatic counterpart of the empty-file error and guards callers from meaningless parse attempts.","triggerScenarios":"Calling $loader->load($xml) with '' — typically because the string was built from a variable that was never set, a file_get_contents() that returned false and was cast to string, or a filtered/composed string that ended up empty.","commonSituations":"Tooling built on top of PHPUnit that assembles XML dynamically (baselines, generated configs); optional XML from environment or database that is absent; string casts of failed I/O calls.","solutions":["Check the string is non-empty before loading: if (trim($xml) === '') { /* handle missing XML */ }","Trace where the empty string came from — usually a failed file_get_contents() or an unset optional config value","Fall back to a valid default document (for example '<phpunit/>') when the XML is optional","Add a unit test for the empty-input branch of your wrapper so it fails loudly where it is produced"],"exampleFix":"// before\n$xml = file_get_contents($path) ?: '';\n$document = (new \\PHPUnit\\Util\\Xml\\Loader)->load($xml);\n// XmlException: Could not parse XML from empty string\n\n// after\n$xml = file_get_contents($path);\nif ($xml === false || trim($xml) === '') {\n    throw new InvalidArgumentException(\"No XML found at {$path}\");\n}\n$document = (new \\PHPUnit\\Util\\Xml\\Loader)->load($xml);","handlingStrategy":"validation","validationCode":"static function assertNonEmptyXmlString(string $xml): void\n{\n    if (trim($xml) === '') {\n        throw new InvalidArgumentException('XML string is empty');\n    }\n}","typeGuard":"static function isParsableXmlString(string $xml): bool\n{\n    return trim($xml) !== '' && str_starts_with(ltrim($xml), '<');\n}","tryCatchPattern":"use PHPUnit\\Util\\Xml\\XmlException;\n\ntry {\n    $document = (new Loader)->load($xml);\n} catch (XmlException $e) {\n    if ($e->getMessage() === 'Could not parse XML from empty string') {\n        // the producer of $xml failed; fetch/regenerate before retrying\n    }\n    throw $e;\n}","preventionTips":["Never cast failed I/O to string; check file_get_contents() === false explicitly","Default optional XML inputs to a valid minimal document, not ''","Cover the empty-input path of XML wrappers with a unit test"],"tags":["phpunit","xml","string-validation"],"backgroundTag":"xml-parse-error","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}