{"record":{"id":"fd803e783c3f3034","repo":"sebastianbergmann/phpunit","slug":"phpt-file-must-not-contain-more-than-one-of-the-se","errorCode":null,"errorMessage":"PHPT file must not contain more than one of the sections --%s--","messagePattern":"PHPT file must not contain more than one of the sections --(.+?)--","errorType":"exception","errorClass":"ConflictingPhptSectionsException","httpStatus":null,"severity":"error","filePath":"src/Runner/Phpt/Parser.php","lineNumber":316,"sourceCode":"        $found = [];\n\n        foreach ($sectionFamily as $name) {\n            if (isset($sections[$name])) {\n                $found[] = $name;\n            }\n        }\n\n        if ($found === []) {\n            throw new InvalidPhptFileException(\n                sprintf(\n                    'PHPT file must contain one of the sections --%s--',\n                    implode('--, --', $sectionFamily),\n                ),\n            );\n        }\n\n        if (count($found) > 1) {\n            throw new ConflictingPhptSectionsException($found);\n        }\n\n        return $found[0];\n    }\n\n    /**\n     * @param array<non-empty-string, string> $sections\n     * @param non-empty-string                $codeSection\n     *\n     * @throws InvalidPhptFileException\n     */\n    private function ensureCodeIsNotEmpty(array $sections, string $codeSection): void\n    {\n        if (isset($sections['FILE']) && $sections['FILE'] !== '') {\n            return;\n        }\n\n        if ($codeSection === 'FILE_EXTERNAL') {","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Runner/Phpt/Parser.php#L298-L334","documentation":"The same ensureExactlyOneSectionOf() then checks count($found) > 1 and throws ConflictingPhptSectionsException('PHPT file must not contain more than one of the sections --%s--'). The code family (FILE, FILEEOF, FILE_EXTERNAL) and the expectation family (EXPECT, EXPECT_EXTERNAL, EXPECTF, EXPECTF_EXTERNAL, EXPECTREGEX, EXPECTREGEX_EXTERNAL) are mutually exclusive within their family: exactly one member of each may appear.","triggerScenarios":"A .phpt containing both --FILE-- and --FILE_EXTERNAL--, or both --EXPECT-- and --EXPECTF--, or any other pair from the same family.","commonSituations":"Switching an expectation from --EXPECT-- to --EXPECTF-- in place and forgetting to delete the old block; merging tests; copy-pasting a block that already exists.","solutions":["Keep exactly one member of each family: delete the alternative code or expectation section.","If you want both exact and fuzzy checks, split them into two separate .phpt files."],"exampleFix":"-- before\n--FILE--\necho 'Hello';\n--FILE_EXTERNAL--\nhello.php\n\n-- after\n--FILE_EXTERNAL--\nhello.php","handlingStrategy":"validation","validationCode":"function assertPhptSectionFamiliesExclusive(string $phptFile): void\n{\n    $body = (string) file_get_contents($phptFile);\n    $families = [\n        ['FILE--', 'FILEEOF--', 'FILE_EXTERNAL--'],\n        ['EXPECT--', 'EXPECT_EXTERNAL--', 'EXPECTF--', 'EXPECTF_EXTERNAL--', 'EXPECTREGEX--', 'EXPECTREGEX_EXTERNAL--'],\n    ];\n\n    foreach ($families as $family) {\n        $found = array_filter($family, fn (string $s) => str_contains($body, '--' . $s));\n        if (count($found) > 1) {\n            throw new RuntimeException('Conflicting sections: ' . implode(', ', $found));\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When switching an expectation style (EXPECT to EXPECTF), replace the old header rather than adding a new one.","Add a lint step that rejects .phpt files with more than one member per section family."],"tags":["phpunit","phpt","conflicting-sections","parser"],"backgroundTag":"conflicting-config-sections","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}