Intervention/image · error · LogicException

Specialized class '{static::class}' must override encode()

Error message

Specialized class '{static::class}' must override encode()

What it means

AbstractEncoder::encode() is the generic fallback that forwards to $image->encode($this); encoder classes marked as SpecializedInterface must override it with a real implementation. Hitting this LogicException means a specialized encoder class was left without its own encode() method - an authoring defect in a custom or third-party encoder, not a usage error.

Source

Thrown at src/Drivers/AbstractEncoder.php:36

{
    use CanBuildStream;

    /**
     * Default encoding quality.
     */
    public const int DEFAULT_QUALITY = 75;

    /**
     * {@inheritdoc}
     *
     * @see EncoderInterface::encode()
     *
     * @throws LogicException
     */
    public function encode(ImageInterface $image): EncodedImageInterface
    {
        if ($this instanceof SpecializedInterface) {
            throw new LogicException(
                "Specialized class '" . static::class . "' must override encode()",
            );
        }

        return $image->encode($this);
    }

    /**
     * Build new stream, run callback with it and return result as encoded image.
     *
     * @throws InvalidArgumentException
     * @throws StreamException
     */
    protected function createEncodedImage(callable $callback, ?string $mediaType = null): EncodedImage
    {
        $stream = self::buildStreamOrFail();
        $callback($stream);

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Add the encode(ImageInterface $image): EncodedImageInterface override to the specialized encoder class
  2. Do not implement SpecializedInterface on encoders that are meant to stay generic
  3. If the encoder comes from a package, report it upstream and pin to a working version meanwhile

Example fix

// before
class AvifEncoder extends GenericAvifEncoder implements SpecializedInterface
{
    // encode() missing
}

// after
class AvifEncoder extends GenericAvifEncoder implements SpecializedInterface
{
    public function encode(ImageInterface $image): EncodedImageInterface
    {
        // driver-specific encoding...
    }
}
Defensive patterns

Strategy: try-catch

Type guard

function encoderOverridesEncode(string $class): bool
{
    return (new \ReflectionMethod($class, 'encode'))->getDeclaringClass()->getName() !== \Intervention\Image\Drivers\AbstractEncoder::class;
}

Try / catch

try {
    $encoded = $image->encode(new MySpecializedEncoder());
} catch (LogicException $e) {
    // encoder authoring bug - implement encode() in the specialized class
}

Prevention

When it happens

Trigger: Encoding with a custom/third-party specialized encoder that implements SpecializedInterface but does not override encode() - e.g. an encoder copied from a built-in one with the encode() body removed, reached via toJpg()/toPng()/encode().

Common situations: Writing custom specialized encoders (extra formats, extra drivers) and forgetting the override; partial copies of built-in encoders.

Related errors


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