Intervention/image · error · InvalidArgumentException

Image source must be of type Intervention\Image\EncodedImage

Error message

Image source must be of type Intervention\Image\EncodedImage

What it means

Contract violation of EncodedImageObjectDecoder::decode: the input does not implement EncodedImageInterface. Note the message names the concrete EncodedImage class while the check accepts any EncodedImageInterface implementation — a slight mismatch, but the meaning is the same: only encoded-image value objects belong here. InvalidArgumentException, raised before any decoding.

Source

Thrown at src/Drivers/Gd/Decoders/EncodedImageObjectDecoder.php:43

    {
        return $input instanceof EncodedImageInterface;
    }

    /**
     * {@inheritdoc}
     *
     * @see DecoderInterface::decode()
     *
     * @throws InvalidArgumentException
     * @throws ImageDecoderException
     * @throws DriverException
     * @throws StateException
     * @throws NotSupportedException
     */
    public function decode(mixed $input): ImageInterface
    {
        if (!$input instanceof EncodedImageInterface) {
            throw new InvalidArgumentException('Image source must be of type ' . EncodedImage::class);
        }

        try {
            return parent::decode($input->toString());
        } catch (DecoderException) {
            throw new ImageDecoderException(EncodedImage::class . ' contains unsupported image type');
        }
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Route inputs through ImageManager::read(), which dispatches by type and will send strings/binary to the correct decoder
  2. Construct the expected type first: new EncodedImage($binary, 'image/png') from Intervention\Image, then pass that object
  3. If interoperating with v2 artifacts, re-create them as v3 objects (read the old bytes, ->encode()) rather than passing old objects
  4. Type-guard: $input instanceof EncodedImageInterface before invoking the decoder

Example fix

// before
$decoder = new EncodedImageObjectDecoder();
$image = $decoder->decode($rawPngString);
// InvalidArgumentException: Image source must be of type Intervention\Image\EncodedImage

// after
$image = $manager->read(new \Intervention\Image\EncodedImage($rawPngString, 'image/png'));
// or simply: $image = $manager->read($rawPngString);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!$input instanceof \Intervention\Image\Interfaces\EncodedImageInterface) {
    throw new InvalidArgumentException('Expected EncodedImage, got ' . get_debug_type($input));
}

Type guard

/**
 * @param mixed $input
 */
function isEncodedImage(mixed $input): bool
{
    return $input instanceof \Intervention\Image\Interfaces\EncodedImageInterface;
}

Prevention

When it happens

Trigger: Calling EncodedImageObjectDecoder->decode() directly with a plain string, GdImage, SplFileInfo, or an unrelated DTO; passing an EncodedImageInterface implementation from a different major version of the library (v2's image objects do not implement the v3 interface); custom routing that forwards every input to this decoder.

Common situations: Upgrading Intervention Image from v2 to v3 where older value objects circulate in cached events/queues; manual decoder wiring; serializers that resurrect objects without the interface; feature tests invoking decoders in isolation.

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


AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23). Data as JSON: /api/errors/c416dbc5c21288b0. Report an issue: GitHub.