symfony/finder · error · InvalidArgumentException
Invalid PHP callback.
Error message
Invalid PHP callback.
What it means
CustomFilterIterator requires every entry of the $filters array to be a PHP callable; if any element is not callable it throws InvalidArgumentException('Invalid PHP callback.') before filtering begins. The library needs real callbacks to apply the custom acceptance logic.
Solutions
- Ensure each filter is callable: closure, 'function' name, ['Class','method'] / 'Class::method' existing, or invokable object
- Validate with is_callable($filter) before constructing
- If filters come from config, map/whitelist them to real PHP callables
Example fix
// before $finder->filter(['nonexistent_function']); // after $finder->filter([static fn (\SplFileInfo $f) => $f->getExtension() === 'php']);
Defensive patterns
Strategy: type-guard
Validate before calling
foreach ($filters as $f) { if (!is_callable($f)) { throw new \InvalidArgumentException('Filter is not callable'); } } Type guard
function allCallable(array $filters): bool { return array_all($filters, fn ($f) => is_callable($f)); } Try / catch
try { $finder->filter($filters); } catch (\InvalidArgumentException $e) { /* handle non-callable filter */ } Prevention
- Always wrap filters as closures when the source is config or user input
- Verify 'Class::method' strings exist (method_exists) before passing
- Keep exclusion/filter arrays flat and typed at the boundary
When it happens
Trigger: new CustomFilterIterator($iterator, ['strlen', 42]) or Finder::filter([null]) — passing an array containing a non-callable, a method string for a nonexistent method used as a single string, or an object without __invoke.
Common situations: Config-driven filters read as strings/arrays that aren't callables, typos in 'Class::method' strings, passing [object, 'method'] arrays where the method doesn't exist so is_callable fails.
Understand the failure class
Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.
Related errors
- Invalid operator " ".
- Invalid PHP callback.
- The SortableIterator takes a PHP callable or a valid…
- Don't understand " " as a date test.
- Don't understand " " as a number test.
AI-assisted analysis of symfony/finder@4d6c057bfd (2026-09-13).
Data as JSON: /api/errors/b8a05398b6304c7b.
Report an issue: GitHub.
Appendix: source
Thrown at Iterator/CustomFilterIterator.php:38
* @author Fabien Potencier <fabien@symfony.com>
*
* @extends \FilterIterator<string, \SplFileInfo>
*/
class CustomFilterIterator extends \FilterIterator
{
private array $filters = [];
/**
* @param \Iterator<string, \SplFileInfo> $iterator The Iterator to filter
* @param callable[] $filters An array of PHP callbacks
*
* @throws \InvalidArgumentException
*/
public function __construct(\Iterator $iterator, array $filters)
{
foreach ($filters as $filter) {
if (!\is_callable($filter)) {
throw new \InvalidArgumentException('Invalid PHP callback.');
}
}
$this->filters = $filters;
parent::__construct($iterator);
}
/**
* Filters the iterator values.
*/
public function accept(): bool
{
$fileinfo = $this->current();
foreach ($this->filters as $filter) {
if (false === $filter($fileinfo)) {
return false;
}View on GitHub (pinned to 4d6c057bfd)