Intervention/image · error · InvalidArgumentException
Image source must be of type SplFileInfo
Error message
Image source must be of type SplFileInfo
What it means
SplFileInfoImageDecoder::decode() was called with a value that is not an SplFileInfo. Normally ImageManager::read() routes input via supports() (instanceof SplFileInfo), so this only fires when the decoder is invoked directly with a wrong type. Symfony's File and UploadedFile extend SplFileInfo and pass the check.
Source
Thrown at src/Drivers/Imagick/Decoders/SplFileInfoImageDecoder.php:49
}
/**
* {@inheritdoc}
*
* @see DecoderInterface::decode()
*
* @throws InvalidArgumentException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException
* @throws FileNotReadableException
* @throws ImageDecoderException
* @throws DriverException
* @throws StateException
*/
public function decode(mixed $input): ImageInterface
{
if (!$input instanceof SplFileInfo) {
throw new InvalidArgumentException('Image source must be of type ' . SplFileInfo::class);
}
try {
return parent::decode(self::filePathFromSplFileInfoOrFail($input));
} catch (DecoderException) {
throw new ImageDecoderException(SplFileInfo::class . ' contains unsupported image type');
}
}
}
View on GitHub (pinned to 5598b9e397)
Solutions
- Use ImageManager::read($file) and let the chain route - Symfony File/UploadedFile instances are supported natively
- If calling decode() directly, guard with instanceof SplFileInfo or supports() first
- For plain path strings, pass the string itself - the FilePathImageDecoder handles it
Example fix
// before
$decoder = new SplFileInfoImageDecoder($driver);
$image = $decoder->decode('/path/to/image.jpg'); // string, not SplFileInfo
// after
$image = $manager->read(new SplFileInfo('/path/to/image.jpg'));
// or simply: $manager->read('/path/to/image.jpg'); Defensive patterns
Strategy: type-guard
Type guard
function isSplFileInfo(mixed $value): bool
{
return $value instanceof \SplFileInfo; // Symfony File/UploadedFile also pass
} Prevention
- Route file objects through ImageManager::read() so supports() dispatches correctly
- Pass plain strings directly - the path decoder handles them without wrapping
When it happens
Trigger: Manually calling the decoder with a plain string path, an SplFileObject-less resource, or an object that only duck-types a file path; custom pipelines bypassing the manager.
Common situations: Wrappers that normalize sources to strings but hand them to the SplFileInfo decoder; refactors from path strings to file objects done only at the call site.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- Image source must be binary data of type string or instance
- Image source must be data uri scheme of type string or Inter
- Image source must be of type Intervention\Image\EncodedImage
- Image source must be of type GdImage
- Image source must be an instance of Imagick
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/d3d525a58c6dc90b.
Report an issue: GitHub.