{"record":{"id":"b012b26db9c08a3a","repo":"sebastianbergmann/phpunit","slug":"parameter-s-does-not-exist","errorCode":null,"errorMessage":"Parameter \"%s\" does not exist","messagePattern":"Parameter \"(.+?)\" does not exist","errorType":"exception","errorClass":"ParameterDoesNotExistException","httpStatus":null,"severity":"error","filePath":"src/Runner/Extension/ParameterCollection.php","lineNumber":54,"sourceCode":"     * @param array<string, string> $parameters\n     */\n    private function __construct(array $parameters)\n    {\n        $this->parameters = $parameters;\n    }\n\n    public function has(string $name): bool\n    {\n        return array_key_exists($name, $this->parameters);\n    }\n\n    /**\n     * @throws ParameterDoesNotExistException\n     */\n    public function get(string $name): string\n    {\n        if (!array_key_exists($name, $this->parameters)) {\n            throw new ParameterDoesNotExistException($name);\n        }\n\n        return $this->parameters[$name];\n    }\n}\n","sourceCodeStart":36,"sourceCodeEnd":60,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Runner/Extension/ParameterCollection.php#L36-L60","documentation":"Runner extensions receive a ParameterCollection built from the <parameter name=\"...\" value=\"...\"/> child elements of the extension's <bootstrap> block in phpunit.xml. get(string $name) throws ParameterDoesNotExistException(sprintf('Parameter \"%s\" does not exist', $name)) when no parameter with exactly that name was configured. The sibling method has(string $name) is the safe boolean check.","triggerScenarios":"Calling $parameters->get('foo') in an extension's bootstrap() when phpunit.xml has no <parameter name=\"foo\" .../> element for that extension, or when the code and XML names differ in spelling or case (the array_key_exists lookup is exact and case-sensitive).","commonSituations":"Typo between the XML attribute and the extension code; CI using a different phpunit.xml that lacks the parameter; upgrading an extension that renamed its parameters; forgetting that parameters must be strings and always present (no defaults exist at this layer).","solutions":["Add the missing parameter in phpunit.xml inside the extension element: <bootstrap class=\"Vendor\\MyExtension\"><parameter name=\"foo\" value=\"bar\"/></bootstrap>.","Verify the exact name and casing used by the extension; the lookup is case-sensitive.","In extension code, guard with has() and provide your own default: $value = $parameters->has('foo') ? $parameters->get('foo') : 'default';"],"exampleFix":"<!-- before (phpunit.xml) -->\n<extensions>\n    <bootstrap class=\"Vendor\\MyExtension\"/>\n</extensions>\n\n<!-- after -->\n<extensions>\n    <bootstrap class=\"Vendor\\MyExtension\">\n        <parameter name=\"apiKey\" value=\"secret\"/>\n    </bootstrap>\n</extensions>","handlingStrategy":"type-guard","validationCode":"// in extension bootstrap(), before any get() call\nif (!$parameters->has('apiKey')) {\n    throw new \\RuntimeException(\n        'MyExtension requires \"apiKey\": add <parameter name=\"apiKey\" value=\"...\"/> to the <bootstrap> element in phpunit.xml'\n    );\n}\n$apiKey = $parameters->get('apiKey');","typeGuard":"final class SafeParameters\n{\n    public function __construct(\n        private readonly \\PHPUnit\\Runner\\Extension\\ParameterCollection $parameters,\n    ) {\n    }\n\n    public function optional(string $name, string $default): string\n    {\n        return $this->parameters->has($name)\n            ? $this->parameters->get($name)\n            : $default;\n    }\n}","tryCatchPattern":null,"preventionTips":["Always guard optional parameters with has(); for required ones, check has() first and throw a message that shows the exact XML snippet to add.","Keep parameter names in a single class constant shared between documentation and code to prevent spelling drift.","Lint the effective phpunit.xml in CI so missing <parameter> elements fail at configuration-validation time."],"tags":["phpunit","extension","configuration","xml","parameters"],"backgroundTag":"missing-config-parameter","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}