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
- Add the encode(ImageInterface $image): EncodedImageInterface override to the specialized encoder class
- Do not implement SpecializedInterface on encoders that are meant to stay generic
- 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
- Always override encode() when implementing SpecializedInterface on encoders
- Reflection-test custom encoders for the override in your test suite
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
- Result must be instance of {ImageInterface::class}
- Result must be instance of {ColorInterface::class}
- Option ${key} does not exist on {this::class}
- Quality must be in range 0 to 100
- Unable to find file extension from empty string
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/beb40128f55f44f3.
Report an issue: GitHub.