Intervention/image · error · InvalidArgumentException

Image source must be data uri scheme of type string or Inter

Error message

Image source must be data uri scheme of type string or Intervention\Image\DataUri

What it means

Contract violation of DataUriImageDecoder::decode: the input is neither a DataUri instance nor a PHP string (e.g. null, array, int, or another object). The decoder cannot interpret such a value as a data URI, so an InvalidArgumentException is thrown. In the normal ImageManager chain this is pre-filtered by supports() (only 'data:'-prefixed strings or DataUri objects), so it mainly bites on direct decoder usage or custom routing.

Source

Thrown at src/Drivers/Gd/Decoders/DataUriImageDecoder.php:54

     *
     * @throws InvalidArgumentException
     * @throws DriverException
     * @throws ImageDecoderException
     * @throws StateException
     * @throws NotSupportedException
     */
    public function decode(mixed $input): ImageInterface
    {
        if ($input instanceof DataUri) {
            try {
                return parent::decode($input->data());
            } catch (DecoderException) {
                throw new ImageDecoderException('Data Uri contains unsupported image type');
            }
        }

        if (!is_string($input)) {
            throw new InvalidArgumentException(
                'Image source must be data uri scheme of type string or ' . DataUri::class,
            );
        }

        try {
            return parent::decode(DataUri::parse($input)->data());
        } catch (DecoderException) {
            throw new ImageDecoderException('Data Uri contains unsupported image type');
        }
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Route through ImageManager::read(), whose supports() checks (str_starts_with($input, 'data:') or DataUriInterface) select the right decoder
  2. Type-guard before calling: is_string($input) || $input instanceof DataUri
  3. Normalize inputs early: cast objects to string, handle null with a default or an error
  4. If the input is a bare base64 string (no data: prefix), send it to the base64 path instead of the data-URI decoder

Example fix

// before
$decoder = new DataUriImageDecoder();
$image = $decoder->decode($request->input('logo')); // null when field absent
// InvalidArgumentException: Image source must be data uri scheme ...

// after
$value = $request->input('logo');
if (is_string($value) && str_starts_with($value, 'data:')) {
    $image = $manager->read($value);
} else {
    throw new InvalidArgumentException('logo must be a data URI string.');
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!is_string($input) && !$input instanceof \Intervention\Image\DataUri) {
    throw new InvalidArgumentException('Expected data URI string or DataUri object, got ' . get_debug_type($input));
}

Type guard

/**
 * @param mixed $input
 */
function isDataUriInput(mixed $input): bool
{
    return $input instanceof \Intervention\Image\DataUri
        || (is_string($input) && str_starts_with($input, 'data:'));
}

Prevention

When it happens

Trigger: Calling DataUriImageDecoder->decode() manually with a non-string value; passing a PSR-7 Uri object, an SplFileInfo, or null from an optional request field; feeding the output of DataUri::parse() on a failure path that returned a non-string sentinel.

Common situations: Custom pipelines that pick decoders explicitly; refactors that changed upstream types; nullable inputs reaching the decoder after a skipped validation step; tests exercising decoder contracts with mixed values.

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/52e4c06a755d9769. Report an issue: GitHub.