sebastianbergmann/phpunit · error · InvalidDataProviderException

Data set %s provided by %s is invalid, expected array but go

Error message

Data set %s provided by %s is invalid, expected array but got %s

What it means

PHPUnit called the data provider method named in your #[DataProvider] or #[DataProviderExternal] attribute and validated each data set it returned. Every value in a provider's iterable must be a plain array whose elements are passed as arguments to the test method. This error names the offending data set key, the provider (Class::method), and the actual type received instead of an array.

Source

Thrown at src/Metadata/Api/DataProvider.php:197

            try {
                foreach ($data as $key => $value) {
                    if (!is_int($key) && !is_string($key)) {
                        throw new InvalidDataProviderException(
                            sprintf(
                                'The key must be an integer or a string, %s given',
                                get_debug_type($key),
                            ),
                        );
                    }

                    if ($key === '') {
                        throw new InvalidDataProviderException(
                            'The key must not be an empty string',
                        );
                    }

                    if (!is_array($value)) {
                        throw new InvalidDataProviderException(
                            sprintf(
                                'Data set %s provided by %s is invalid, expected array but got %s',
                                $this->formatKey($key),
                                $providerLabel,
                                get_debug_type($value),
                            ),
                        );
                    }

                    if ($validateArgumentCount && $testMethodNumberOfParameters < count($value)) {
                        $this->triggerWarningForArgumentCount(
                            $testMethod,
                            $this->formatKey($key),
                            $providerLabel,
                            count($value),
                            $testMethodNumberOfParameters,
                        );
                    }

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Open the provider named in the message and jump to the data set key it reports ("key" or #index).
  2. Wrap each row in an array so it maps onto test method parameters: return [[1, 2], [3, 4]]; or yield 'name' => [$value].
  3. If the test takes one parameter, keep each row a one-element array: [['hello'], ['world']].
  4. Re-run with --filter <testMethodName> to verify only this provider is affected.

Example fix

// before
public static function provider(): array
{
    return ['hello', 'world'];
}

// after
public static function provider(): array
{
    return [['hello'], ['world']];
}
Defensive patterns

Strategy: validation

Validate before calling

// Meta-test: assert provider shape before PHPUnit consumes it
public function testProviderYieldsArgumentArrays(): void
{
    foreach (MyTest::provider() as $key => $value) {
        self::assertIsArray($value, sprintf('Data set %s is not an argument array', (string) $key));
    }
}

Type guard

function isValidProviderData(mixed $data): bool
{
    if (!is_iterable($data)) {
        return false;
    }

    foreach ($data as $key => $value) {
        if ((!is_int($key) && !is_string($key)) || $key === '' || !is_array($value)) {
            return false;
        }
    }

    return true;
}

Prevention

When it happens

Trigger: A #[DataProvider('provider')] method returns an iterable containing at least one non-array value: return ['foo', 'bar']; (list of strings instead of list of argument arrays), yield 'user' => $userObject; (bare object row), or a generator that yields scalars.

Common situations: Providers migrated from frameworks where rows are single values; yield $key => $value instead of yield $key => [$value]; providers built from json_decode()/fixture files whose rows decode to scalars or objects; refactoring a single-parameter test and forgetting to wrap values.

Related errors


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/ba4aecbaa877c10b. Report an issue: GitHub.