{"record":{"id":"0d32ab8231f2cdff","repo":"Intervention/image","slug":"image-source-must-be-a-resource-of-type-file-or","errorCode":null,"errorMessage":"Image source must be a resource of type 'file' or 'stream'","messagePattern":"Image source must be a resource of type 'file' or 'stream'","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Gd/Decoders/StreamImageDecoder.php","lineNumber":43,"sourceCode":"        return is_resource($input);\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see DecoderInterface::decode()\n     *\n     * @throws InvalidArgumentException\n     * @throws StreamException\n     * @throws DriverException\n     * @throws StateException\n     * @throws ImageDecoderException\n     * @throws NotSupportedException\n     */\n    public function decode(mixed $input): ImageInterface\n    {\n        if (!is_resource($input) || !in_array(get_resource_type($input), ['file', 'stream'])) {\n            throw new InvalidArgumentException(\"Image source must be a resource of type 'file' or 'stream'\");\n        }\n\n        $contents = '';\n        $result = rewind($input);\n\n        if ($result === false) {\n            throw new StreamException('Failed to rewind position of stream');\n        }\n\n        while (!feof($input)) {\n            $chunk = fread($input, 1024);\n            if ($chunk === false) {\n                throw new StreamException('Failed to read image from stream');\n            }\n\n            $contents .= $chunk;\n        }\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Gd/Decoders/StreamImageDecoder.php#L25-L61","documentation":"StreamImageDecoder accepts only a PHP resource whose get_resource_type() is 'file' or 'stream'. Any other input (string, object, closed resource, or a resource of another type like a curl handle) triggers InvalidArgumentException before any reading starts.","triggerScenarios":"$manager->decodeStream($psr7Stream) where $psr7Stream is a PSR-7 StreamInterface object; passing a curl handle; passing a resource already closed by fclose(); passing a plain string path.","commonSituations":"Confusing Guzzle/Symfony stream objects with native PHP resources, frameworks whose file APIs return objects (Symfony UploadedFile), resources from proc_open or curl reused as image sources.","solutions":["Pass a real resource from fopen($path, 'rb') or a php://temp handle","For PSR-7 streams, use (string) $stream or $stream->getContents() and read the string instead","For plain strings, call $manager->read($string) and let BinaryImageDecoder handle it"],"exampleFix":"// before\n$image = $manager->decodeStream($response->getBody()); // object, not resource\n\n// after\n$stream = fopen('php://temp', 'rb+');\nfwrite($stream, $response->getBody()->getContents());\nrewind($stream);\n$image = $manager->decodeStream($stream);\n// or simply: $image = $manager->read($response->getBody()->getContents());","handlingStrategy":"type-guard","validationCode":"if (!is_resource($stream) || !in_array(get_resource_type($stream), ['file', 'stream'], true)) {\n    throw new InvalidArgumentException('Expected a file/stream resource');\n}\n$manager->decodeStream($stream);","typeGuard":"function isFileStream(mixed $value): bool\n{\n    return is_resource($value) && in_array(get_resource_type($value), ['file', 'stream'], true);\n}","tryCatchPattern":"try {\n    $image = $manager->decodeStream($source);\n} catch (InvalidArgumentException $e) {\n    $image = $manager->read((string) $source); // fall back to string decoding\n}","preventionTips":["Convert PSR-7/framework stream objects to strings or php://temp first","Never pass curl or proc handles as image sources","Use $manager->read() for strings and paths"],"tags":["stream","type-check","psr-7","gd"],"backgroundTag":"invalid-argument-type","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}