Intervention/image · error · Intervention\Image\Exceptions\InvalidArgumentException

Unable to decode from null

Error message

Unable to decode from null

What it means

InputHandler::handle() is the funnel behind ImageManager::read()/parse() and color parsing; it rejects null outright because there is no decoder for 'nothing'. The check precedes decoder selection, so it fires before any 'Unprocessable input' logic. Receiving this error means your code passed a null variable into the read pipeline — typically a missing upload, an absent config value, or a failed lookup.

Source

Thrown at src/InputHandler.php:101

     */
    public static function usingDecoders(array $decoders, ?DriverInterface $driver = null): self
    {
        return new self($decoders, $driver);
    }

    /**
     * {@inheritdoc}
     *
     * @see InputHandlerInterface::handle()
     *
     * @throws InvalidArgumentException
     * @throws NotSupportedException
     * @throws DriverException
     */
    public function handle(mixed $input): ImageInterface|ColorInterface
    {
        if ($input === null) {
            throw new InvalidArgumentException('Unable to decode from null');
        }

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

        // if handler has only one single decoder run it can run directly
        if (count($this->decoders) === 1) {
            return $this->decoders()->current()->decode($input);
        }

        // multiple decoders: try to find the matching decoder for the input
        foreach ($this->decoders() as $decoder) {
            if ($decoder->supports($input)) {
                return $decoder->decode($input);
            }
        }

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Check for null before reading: if ($file = $request->file('avatar')) { ... }
  2. Use strict access ($array['key'] ?? null) and branch on the result instead of passing it through
  3. For optional uploads, skip processing entirely when the input is absent rather than relying on the library to validate
  4. Add a typed intermediary: function readImage(mixed $src): ImageInterface that throws your own descriptive error on null

Example fix

// before
$image = $manager->read($request->file('avatar')); // null when no upload

// after
if (null === ($file = $request->file('avatar'))) {
    abort(422, 'Avatar upload is required.');
}
$image = $manager->read($file->getPathname());
Defensive patterns

Strategy: validation

Validate before calling

$source = $request->file('avatar')?->getPathname();
if ($source === null) {
    abort(422, 'Avatar upload is required.');
}
$image = $manager->read($source);

Type guard

function isReadableInput(mixed $input): bool
{
    return $input !== null && $input !== '';
}

Try / catch

try {
    $image = $manager->read($input);
} catch (InvalidArgumentException $e) {
    // null input is a caller bug: fail with a clear 422, never retry
}

Prevention

When it happens

Trigger: $manager->read(null), $manager->read($request->file('avatar')) when no file was uploaded (Laravel returns null), read($cache->get('image')) on cache miss, or parse(null) in color handling flows.

Common situations: HTTP endpoints processing optional uploads without presence checks, cache/session lookups that return null, or array access on missing keys under permissive fetch. Common after refactoring when a variable that was always set becomes conditional.

Understand the failure class

Related errors


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