{"record":{"id":"4fa83d593bdf1d35","repo":"sebastianbergmann/phpunit","slug":"cannot-double-using-a-method-list-that-contains-du","errorCode":null,"errorMessage":"Cannot double using a method list that contains duplicates: \"%s\" (duplicate: \"%s\")","messagePattern":"Cannot double using a method list that contains duplicates: \"(.+?)\" \\(duplicate: \"(.+?)\"\\)","errorType":"exception","errorClass":"DuplicateMethodException","httpStatus":null,"severity":"error","filePath":"src/Framework/MockObject/Generator/Generator.php","lineNumber":720,"sourceCode":"     * @param ?list<non-empty-string> $methods\n     *\n     * @throws DuplicateMethodException\n     * @throws InvalidMethodNameException\n     */\n    private function ensureValidMethods(?array $methods): void\n    {\n        if ($methods === null) {\n            return;\n        }\n\n        foreach ($methods as $method) {\n            if (preg_match('~\\A[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*\\z~', (string) $method) === 0) {\n                throw new InvalidMethodNameException((string) $method);\n            }\n        }\n\n        if ($methods !== array_unique($methods)) {\n            throw new DuplicateMethodException($methods);\n        }\n    }\n\n    /**\n     * @throws InvalidClassNameException\n     */\n    private function ensureValidNameForTestDoubleClass(string $className): void\n    {\n        if ($className === '') {\n            return;\n        }\n\n        if (preg_match('~\\A[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*\\z~', $className) === 0) {\n            throw new InvalidClassNameException($className);\n        }\n    }\n\n    /**","sourceCodeStart":702,"sourceCodeEnd":738,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Framework/MockObject/Generator/Generator.php#L702-L738","documentation":"Thrown by Generator::ensureValidMethods() when the method list for a test double fails the $methods !== array_unique($methods) check, i.e. the same method name appears twice. PHPUnit refuses to generate a double whose method list has duplicates because the generated class would define colliding methods.","triggerScenarios":"onlyMethods(['foo', 'foo']) or addMethods(['bar', 'bar']); merging two arrays for the method list where the same name occurs in both, e.g. ->onlyMethods(array_merge($baseMethods, $extraMethods)) with overlapping entries; a data provider that repeats a name.","commonSituations":"Combining a base list of mocked methods with an extra list and forgetting to deduplicate; copy-paste duplication inside a long onlyMethods() array; lists assembled from multiple sources (config + hardcoded) in test helpers.","solutions":["Remove the duplicate entry reported in the message (the message names both the list and the duplicate).","If merging lists dynamically, wrap with array_values(array_unique($methods)) before passing to onlyMethods()/addMethods().","Check you did not pass the same method via both onlyMethods() and addMethods() on the same MockBuilder."],"exampleFix":"// before\n$mock = $this->getMockBuilder(C::class)\n    ->onlyMethods(['load', 'save', 'load'])\n    ->getMock();\n\n// after\n$mock = $this->getMockBuilder(C::class)\n    ->onlyMethods(['load', 'save'])\n    ->getMock();","handlingStrategy":"validation","validationCode":"$methods = array_values(array_unique($methods));\nif (count($methods) !== count(array_unique($methods))) {\n    throw new InvalidArgumentException('duplicates in method list');\n}","typeGuard":"function hasNoDuplicates(array $methods): bool\n{\n    return count($methods) === count(array_unique($methods));\n}","tryCatchPattern":"try {\n    $mock = $builder->onlyMethods($methods)->getMock();\n} catch (PHPUnit\\Framework\\MockObject\\DuplicateMethodException $e) {\n    // deduplicate and retry with array_values(array_unique($methods))\n}","preventionTips":["Deduplicate every dynamically merged method list before passing it to onlyMethods()/addMethods().","Do not list the same method through both onlyMethods() and addMethods() on one builder.","Keep method lists short and literal in tests; long merged arrays are the usual culprit."],"tags":["phpunit","mock-object","duplicate-method","input-validation"],"backgroundTag":"duplicate-list-entries","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}