{"record":{"id":"89432bb3641c888f","repo":"pestphp/pest","slug":"a-test-named-s-already-exists-in-s-please-g","errorCode":null,"errorMessage":"A test named [%s] already exists in [%s]. Please give this test a different description.","messagePattern":"A test named \\[(.+?)\\] already exists in \\[(.+?)\\]\\. Please give this test a different description\\.","errorType":"exception","errorClass":"TestAlreadyExist","httpStatus":null,"severity":"error","filePath":"src/Factories/TestCaseFactory.php","lineNumber":187,"sourceCode":"\n            eval($classCode);\n        } catch (ParseError $caught) {\n            throw new RuntimeException(sprintf(\n                \"Unable to create test case for test file at [%s]. \\n %s\",\n                $filename,\n                $classCode\n            ), 1, $caught);\n        }\n    }\n\n    public function addMethod(TestCaseMethodFactory $method): void\n    {\n        if ($method->description === null) {\n            throw new TestDescriptionMissing($method->filename);\n        }\n\n        if (array_key_exists($method->description, $this->methods)) {\n            throw new TestAlreadyExist($method->filename, $method->description);\n        }\n\n        if (\n            $method->closure instanceof \\Closure &&\n            new \\ReflectionFunction($method->closure)->isStatic()\n        ) {\n\n            throw new TestClosureMustNotBeStatic($method);\n        }\n\n        if (! $method->receivesArguments()) {\n            if (! $method->closure instanceof \\Closure) {\n                throw ShouldNotHappen::fromMessage('The test closure may not be empty.');\n            }\n\n            $arguments = Reflection::getFunctionArguments($method->closure);\n\n            if ($arguments !== []) {","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/pestphp/pest/blob/1af74a215c3a89bc7a44fc6f9322e369eaad2423/src/Factories/TestCaseFactory.php#L169-L205","documentation":"Within a single test file, Pest registers each test by its description; addMethod throws TestAlreadyExist when a description already exists in that file's test case. The check is an exact array_key_exists on the description string, so two tests with the identical description collide even if their bodies differ.","triggerScenarios":"Two it('creates a user', ...) blocks in the same file (classic copy-paste); dataset-driven tests where the same description template is reused without interpolation; describe() blocks in one file reusing the same inner test name across different describes (Pest namespaces describes in output but the factory keys per file).","commonSituations":"Copy-paste test growth; merging branches that both added a test with the same title; refactoring big files by duplicating a block and intending to edit the title later; non-descriptive titles ('works', 'test 1') colliding.","solutions":["Rename the second test to a unique description in that file.","Make duplicated cases data-driven instead of copy-pasted: one test + ->with([[...], [...]]).","Prefix titles inside describe blocks if you intentionally repeat inner names (check the file's other descriptions first — the message names both file and description)."],"exampleFix":"// before\nit('validates email', fn () => ...);\nit('validates email', fn () => ...); // duplicate\n// after\nit('validates email format', fn () => ...);\nit('validates email domain', fn () => ...);","handlingStrategy":"validation","validationCode":"// guard in test-generator helpers:\nstatic $seen = [];\nif (isset($seen[$description])) {\n    throw new LogicException(\"Duplicate test description [{$description}]\");\n}\n$seen[$description] = true;\ntest($description, $closure);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When copy-pasting a test, change the description in the same edit.","Prefer datasets over duplicated near-identical tests.","Use descriptive, scenario-specific titles; generic ones ('works') collide easily within a file."],"tags":["pest","duplicate","test-description","load-time"],"backgroundTag":"duplicate-definition","analyzedSha":"1af74a215c3a89bc7a44fc6f9322e369eaad2423","analyzedAt":"2026-08-21T02:16:38.132Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}