Intervention/image · error · InvalidArgumentException

Image source must be binary data of type string or instance

Error message

Image source must be binary data of type string or instance of Stringable

What it means

Contract violation of BinaryImageDecoder::decode: the input is neither a PHP string nor a Stringable object, so it cannot be raw image binary. This InvalidArgumentException is a programmer-error guard — normal manager routing (supports() via couldBeBinaryData) already filters non-strings, so hitting it means the decoder was called directly or with an unexpected value type.

Source

Thrown at src/Drivers/Gd/Decoders/BinaryImageDecoder.php:47

    {
        return $this->couldBeBinaryData($input);
    }

    /**
     * {@inheritdoc}
     *
     * @see DecoderInterface::decode()
     *
     * @throws InvalidArgumentException
     * @throws ImageDecoderException
     * @throws DriverException
     * @throws StateException
     * @throws NotSupportedException
     */
    public function decode(mixed $input): ImageInterface
    {
        if (!is_string($input) && !$input instanceof Stringable) {
            throw new InvalidArgumentException(
                'Image source must be binary data of type string or instance of ' . Stringable::class,
            );
        }

        $input = (string) $input;

        if ($input === '') {
            throw new InvalidArgumentException('Unable to decode binary data from empty string');
        }

        return $this->isGifFormat($input) ? $this->decodeGif($input) : $this->decodeBinary($input);
    }

    /**
     * Decode image from given binary data
     *
     * @throws InvalidArgumentException
     * @throws ImageDecoderException

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Cast or stringify the value before calling: (string) $value, or fetch stream contents with (string) $stream
  2. Add a type guard: is_string($input) || $input instanceof Stringable before invoking decode
  3. Make the calling code's signature honest (string $input instead of mixed) so PHP itself rejects bad types earlier
  4. If you meant to read a file path, stream, or GdImage, route through ImageManager::read() instead of the binary decoder directly

Example fix

// before
$decoder = new BinaryImageDecoder();
$image = $decoder->decode($request->file('avatar')); // UploadedFile object
// InvalidArgumentException: Image source must be binary data ...

// after
$image = $manager->read($request->file('avatar')->getContent());
// or let the manager auto-route: $manager->read($request->file('avatar')->getRealPath())
Defensive patterns

Strategy: type-guard

Validate before calling

if (!is_string($input) && !$input instanceof \Stringable) {
    throw new InvalidArgumentException('Expected binary string, got ' . get_debug_type($input));
}

Type guard

/**
 * @param mixed $input
 */
function isBinaryLike(mixed $input): bool
{
    return is_string($input) || $input instanceof \Stringable;
}

Try / catch

try {
    $image = $decoder->decode($input);
} catch (\Intervention\Image\Exceptions\InvalidArgumentException $e) {
    // programmer error: fix the call site, do not catch-and-continue in production
    throw $e;
}

Prevention

When it happens

Trigger: Calling BinaryImageDecoder (or a subclass like Base64ImageDecoder) ->decode() directly with null, an int, an array, a PSR-7 stream, or an SplFileObject; passing a resource from file_get_contents(..., use include path) style calls that can return false/null; untyped mixed values flowing from decoded JSON into decoder calls.

Common situations: Custom decoder chains wired manually into a factory; refactorings that changed an upstream return type from string to object/null; optional fields (nullable string) passed without a null check; unit tests exercising the decoder with scalar literals.

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/25726c03b4a8bcee. Report an issue: GitHub.