Intervention/image · error · InvalidArgumentException
Image source must be a resource of type "file" or "stream"
Error message
Image source must be a resource of type "file" or "stream"
What it means
StreamImageDecoder::decode() requires a PHP resource whose get_resource_type() is 'file' or 'stream'. Passing any other resource type - or an already-closed resource (is_resource() returns false after fclose) - fails here. Usually hit by calling the decoder directly or by confusing a stream handle with a stream wrapper URL string.
Source
Thrown at src/Drivers/Imagick/Decoders/StreamImageDecoder.php:40
public function supports(mixed $input): bool
{
return is_resource($input);
}
/**
* {@inheritdoc}
*
* @see DecoderInterface::decode()
*
* @throws InvalidArgumentException
* @throws StreamException
* @throws DriverException
* @throws StateException
*/
public function decode(mixed $input): ImageInterface
{
if (!is_resource($input) || !in_array(get_resource_type($input), ['file', 'stream'])) {
throw new InvalidArgumentException('Image source must be a resource of type "file" or "stream"');
}
$contents = '';
$rewind = rewind($input);
if ($rewind === false) {
throw new StreamException('Failed to rewind position of stream');
}
while (!feof($input)) {
$chunk = fread($input, 1024);
if ($chunk === false) {
throw new StreamException('Failed to read image from stream');
}
$contents .= $chunk;
}
try {View on GitHub (pinned to 5598b9e397)
Solutions
- Open a real handle first: $manager->read(fopen($path, 'rb'))
- For PSR-7 bodies, pass the underlying resource: $manager->read($stream->detach())
- Guard with is_resource($h) && in_array(get_resource_type($h), ['file', 'stream']) before passing
Example fix
// before
$image = $manager->read('php://temp'); // string, not a resource
// after
$handle = fopen('php://temp', 'r+b');
fwrite($handle, $imageBytes);
$image = $manager->read($handle); Defensive patterns
Strategy: type-guard
Type guard
function isFileStreamResource(mixed $value): bool
{
return is_resource($value)
&& in_array(get_resource_type($value), ['file', 'stream'], true);
} Prevention
- Open handles with fopen() before passing; never pass URL strings or curl handles
- For PSR-7 streams pass ->detach(), and check is_resource() afterwards (detach may be one-shot)
When it happens
Trigger: Passing a cURL handle (curl_init()), a popen() pipe, or a resource closed elsewhere; passing the string 'php://temp' instead of an fopen() handle; passing a PSR-7 StreamInterface object instead of $stream->detach().
Common situations: Refactors from string paths to streams; integrating with PSR-7 request/response bodies; consuming resources produced by curl multi handles.
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/0bf6af5a7114b99d.
Report an issue: GitHub.