Intervention/image · error · InvalidArgumentException
Image source must be of type GdImage
Error message
Image source must be of type GdImage
What it means
Contract violation of NativeObjectDecoder::decode: the input is not a GdImage instance. This GD-driver decoder accepts only native GD resources/objects, so anything else (string, resource, Imagick object, null) triggers an InvalidArgumentException immediately. In the manager's auto-routing supports() filters for GdImage, so this fires mainly on direct decoder calls or miswired custom chains.
Source
Thrown at src/Drivers/Gd/Decoders/NativeObjectDecoder.php:43
*/
public function supports(mixed $input): bool
{
return $input instanceof GdImage;
}
/**
* {@inheritdoc}
*
* @see DecoderInterface::decode()
*
* @throws InvalidArgumentException
* @throws DriverException
* @throws StateException
*/
public function decode(mixed $input): ImageInterface
{
if (!$input instanceof GdImage) {
throw new InvalidArgumentException('Image source must be of type ' . GdImage::class);
}
if (!imageistruecolor($input)) {
$result = imagepalettetotruecolor($input);
if ($result === false) {
throw new DriverException('Failed to convert image to true color');
}
}
imagesavealpha($input, true);
// build image instance
return new Image(
$this->driver(),
new Core([
new Frame($input),
]),
);View on GitHub (pinned to 5598b9e397)
Solutions
- Guard the value: $input instanceof GdImage before invoking decode; check for false after any imagecreate* call
- Let ImageManager::read() do the dispatch — pass binary/paths and let it route to the right decoder
- Convert foreign objects first: Imagick images can be re-encoded to PNG bytes and re-read; older resources are automatically GdImage on PHP >= 8
- Type the upstream API as GdImage instead of mixed so violations surface at the caller
Example fix
// before
$gd = @imagecreatetruecolor(100, 100); // returns GdImage|false
$decoder = new NativeObjectDecoder();
$image = $decoder->decode($gd); // $gd may be false
// InvalidArgumentException: Image source must be of type GdImage
// after
$gd = imagecreatetruecolor(100, 100);
if ($gd === false) {
throw new RuntimeException('GD failed to allocate the canvas');
}
$image = $decoder->decode($gd); Defensive patterns
Strategy: type-guard
Validate before calling
if (!$input instanceof \GdImage) {
throw new InvalidArgumentException('Expected GdImage, got ' . get_debug_type($input));
} Type guard
/**
* @param mixed $input
*/
function isGdImage(mixed $input): bool
{
return $input instanceof \GdImage;
} Prevention
- Check the GdImage|false return of every imagecreate* call before use
- Prefer ImageManager::read() so decoding is dispatched by type
- Never mix Imagick objects and GdImage values in one untyped pipeline
When it happens
Trigger: Calling the native decoder (or a pipeline built on it) with an Imagick object, a file-path string, a GD resource from older PHP (PHP < 8 resources vs GdImage), or null; passing the result of a function that returns GdImage|false without checking the false branch.
Common situations: Migrating pre-PHP-8 code where imagecreate* returned resources; mixed-driver codebases where Imagick and GD objects flow through the same variable; false from a failed imagecreatetruecolor(color-mode) leaking in; unit tests instantiating decoders directly.
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 an instance of Imagick
- Image source must be of type SplFileInfo
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/307269c5e90677b7.
Report an issue: GitHub.