sebastianbergmann/phpunit · error · InvalidDataProviderException
Data Provider method %s::%s() does not return an iterable
Error message
Data Provider method %s::%s() does not return an iterable
What it means
Thrown after invoking the provider method when its return value is not iterable (is_iterable() check fails). Providers must return an array or a Traversable (e.g. generator, ArrayIterator) whose entries are the argument sets for each test run.
Source
Thrown at src/Metadata/Api/DataProvider.php:162
),
);
}
if ($method->getNumberOfParameters() > 0) {
throw new InvalidDataProviderException(
sprintf(
'Data Provider method %s::%s() expects an argument',
$className,
$methodName,
),
);
}
/** @phpstan-ignore staticMethod.dynamicName */
$data = $className::$methodName();
if (!is_iterable($data)) {
throw new InvalidDataProviderException(
sprintf(
'Data Provider method %s::%s() does not return an iterable',
$className,
$methodName,
),
);
}
} catch (Throwable $e) {
Event\Facade::emitter()->dataProviderMethodFinished(
$testMethodValueObject,
...$methodsCalled,
);
throw InvalidDataProviderException::forException($e, $providerLabel);
}
try {
foreach ($data as $key => $value) {View on GitHub (pinned to f123cdb2a2)
Solutions
- Change the provider to always return an array or a generator
- Replace early 'return null/void' paths with 'return []' or 'yield from []'
- If returning a custom collection, convert it with ->toArray() before returning
Example fix
// before
public static function provideCases(): ?array
{
if (!extension_loaded('intl')) {
return null; // -> InvalidDataProviderException
}
return [[1], [2]];
}
// after
public static function provideCases(): array
{
if (!extension_loaded('intl')) {
return [];
}
return [[1], [2]];
} Defensive patterns
Strategy: validation
Validate before calling
// Guard inside the provider itself so consumers always receive an array
public static function provideCases(): array
{
$data = self::buildCases(); // may return null on unsupported setups
return is_iterable($data) ? iterator_to_array($data) : [];
} Prevention
- Declare an explicit ': array' or ': Generator' return type on every provider
- Never let a provider return null; use 'return []' for empty datasets
- Convert custom collections with ->toArray() before returning them
When it happens
Trigger: A provider typed/returning null, a scalar, or an object that does not implement Traversable (e.g. 'public static function provideCases(): ?string' or one that conditionally returns null).
Common situations: Generators with a bug that makes them return null on some path; providers returning a custom collection object instead of an array; early returns left in during refactoring.
Related errors
- Comparison method %s::%s() does not declare bool return type
- Method %s may not return value of type %s, its declared retu
- Data Provider method %s::%s() is not public
- Data Provider method %s::%s() is not static
- Data Provider method %s::%s() expects an argument
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/b06e8c6e95ca1f88.
Report an issue: GitHub.