{"record":{"id":"8ed0a05cf0bb4c62","repo":"sebastianbergmann/phpunit","slug":"the-key-must-not-be-an-empty-string","errorCode":null,"errorMessage":"The key must not be an empty string","messagePattern":"The key must not be an empty string","errorType":"exception","errorClass":"InvalidDataProviderException","httpStatus":null,"severity":"error","filePath":"src/Metadata/Api/DataProvider.php","lineNumber":191,"sourceCode":"                    ...$methodsCalled,\n                );\n\n                throw InvalidDataProviderException::forException($e, $providerLabel);\n            }\n\n            try {\n                foreach ($data as $key => $value) {\n                    if (!is_int($key) && !is_string($key)) {\n                        throw new InvalidDataProviderException(\n                            sprintf(\n                                'The key must be an integer or a string, %s given',\n                                get_debug_type($key),\n                            ),\n                        );\n                    }\n\n                    if ($key === '') {\n                        throw new InvalidDataProviderException(\n                            'The key must not be an empty string',\n                        );\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',\n                                $this->formatKey($key),\n                                $providerLabel,\n                                get_debug_type($value),\n                            ),\n                        );\n                    }\n\n                    if ($validateArgumentCount && $testMethodNumberOfParameters < count($value)) {\n                        $this->triggerWarningForArgumentCount(\n                            $testMethod,","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Metadata/Api/DataProvider.php#L173-L209","documentation":"Thrown while iterating provider data when a dataset key is the empty string ''. The key doubles as the dataset's name in test IDs, output, and result caches, and an empty name would make those ambiguous, so PHPUnit rejects it explicitly.","triggerScenarios":"A provider returning ['' => [...]] or an array whose first element was unset ('unset($data[0])' leaving '' keys); generators yielding '' as a key.","commonSituations":"Providers built from CSV/JSON rows where a column used as the key is blank; array_flip on values containing empty strings; unsetting elements that reindexes to '' through string casts.","solutions":["Give every dataset a meaningful non-empty string key (e.g. '#case ' . $i => $row)","Filter or default blank keys when building the provider: $key === '' ? 'unnamed' : $key","Use array_values($data) to switch to sequential integer keys"],"exampleFix":"// before\npublic static function provideCases(): array\n{\n    $rows = array_flip(array_column($this->csv(), 0)); // blank first column -> '' key\n    ...\n}\n\n// after\npublic static function provideCases(): array\n{\n    $cases = [];\n\n    foreach (array_column($this->csv(), 0) as $i => $name) {\n        $cases['case ' . $i . ': ' . $name] = [$name];\n    }\n\n    return $cases;\n}","handlingStrategy":"validation","validationCode":"// Guard against blank keys from external data\n$cases = [];\n\nforeach ($rows as $i => $row) {\n    $name = trim((string) ($row['name'] ?? ''));\n    $cases[$name !== '' ? $name : 'case ' . $i] = $row;\n}\n\nreturn $cases;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default blank keys to a generated name like 'case ' . $i","Validate CSV/JSON-derived keys before using them as dataset names","Use array_values() when you do not need named datasets"],"tags":["phpunit","data-provider","array-key","empty-key"],"backgroundTag":"invalid-data-provider-key","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}