{"record":{"id":"498685101a29f6f0","repo":"sebastianbergmann/phpunit","slug":"the-key-s-has-already-been-defined-by-s","errorCode":null,"errorMessage":"The key \"%s\" has already been defined by %s","messagePattern":"The key \"(.+?)\" has already been defined by (.+?)","errorType":"exception","errorClass":"InvalidDataProviderException","httpStatus":null,"severity":"error","filePath":"src/Metadata/Api/DataProvider.php","lineNumber":390,"sourceCode":"    {\n        $result                       = [];\n        $testMethodNumberOfParameters = $testMethod->getNumberOfParameters();\n        $testMethodIsNonVariadic      = !$testMethod->isVariadic();\n        $autoIncrementKey             = 0;\n\n        foreach ($testWith as $i => $_testWith) {\n            assert($_testWith instanceof TestWith);\n\n            $providerLabel = sprintf('TestWith#%s attribute', $i);\n            $value         = $_testWith->data();\n\n            if ($_testWith->hasName()) {\n                $key = $_testWith->name();\n\n                assert($key !== null);\n\n                if (array_key_exists($key, $result)) {\n                    throw new InvalidDataProviderException(\n                        sprintf(\n                            'The key \"%s\" has already been defined by %s',\n                            $key,\n                            $result[$key]->label(),\n                        ),\n                    );\n                }\n\n                $formattedKey = $this->formatKey($key);\n            } else {\n                $key          = null;\n                $formattedKey = $this->formatKey($autoIncrementKey);\n            }\n\n            if (!is_array($value)) {\n                throw new InvalidDataProviderException(\n                    sprintf(\n                        'Data set %s provided by %s is invalid, expected array but got %s',","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Metadata/Api/DataProvider.php#L372-L408","documentation":"The test method carries multiple #[TestWith] / #[TestWithJson] attributes, and PHPUnit keys those data sets by the optional name: argument so names appear in test output. Two attributes on the same test method declared the same name; the message names the attribute index (TestWith#N) that registered it first.","triggerScenarios":"Two #[TestWith([...], name: 'edge-case')] attributes, or a #[TestWith] plus a #[TestWithJson], on the same test method using the same name:.","commonSituations":"Copy-pasting an attribute and forgetting to update name:; combining named and JSON variants with generic names like 'data' or 'test'.","solutions":["Rename one of the duplicated name: values on that test method.","Or drop name: entirely — unnamed #[TestWith] data sets are auto-numbered and never collide."],"exampleFix":"// before\n#[TestWith([1], name: 'one')]\n#[TestWith([2], name: 'one')]\n\n// after\n#[TestWith([1], name: 'one')]\n#[TestWith([2], name: 'two')]","handlingStrategy":"validation","validationCode":"// Scan a test method's TestWith attributes for duplicate names before running\n$method = new ReflectionMethod(MyTest::class, 'testX');\n$names = [];\nforeach ($method->getAttributes(TestWith::class) as $attribute) {\n    $name = $attribute->newInstance()->name();\n    if ($name !== null) {\n        self::assertArrayNotHasKey($name, $names, \"Duplicate TestWith name '$name'\");\n        $names[$name] = true;\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give each #[TestWith]/#[TestWithJson] on a method a distinct name:.","Prefer omitting name: when the data itself is self-explanatory.","Codemod/review check: flag repeated name: values within one method's attribute list."],"tags":["phpunit","php","testwith","duplicate-key"],"backgroundTag":"data-provider-duplicate-key","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}