Intervention/image · error · StateException
The stroke color must be fully opaque
Error message
The stroke color must be fully opaque
What it means
StateException from the Imagick text modifier: the stroke color (decoded from the font's strokeColor setting) is transparent while a stroke effect is active. This mirrors the text-fill check - ImageMagick cannot render a stroke outline from a fully transparent color, so the modifier fails before drawing anything.
Source
Thrown at src/Drivers/Imagick/Modifiers/TextModifier.php:96
}
/**
* Create a ImagickDraw object to draw the outline stroke effect on the Image
*
* @throws StateException
* @throws DriverException
* @throws RuntimeException
*/
private function imagickDrawStroke(ImageInterface $image, FontInterface $font): ?ImagickDraw
{
if (!$font->hasStrokeEffect()) {
return null;
}
$color = $this->driver()->decodeColor($font->strokeColor());
if ($color->isTransparent()) {
throw new StateException(
'The stroke color must be fully opaque',
);
}
$color = $this->driver()->colorProcessor($image)->export($color);
return $this->processor()->toImagickDraw($font, $color);
}
/**
* Maybe draw given line of text on frame instance depending on given
* ImageDraw instance. Optionally move line position by given offset.
*
* @throws ModifierException
*/
private function maybeDrawTextline(
FrameInterface $frame,
Line $textline,View on GitHub (pinned to 5598b9e397)
Solutions
- Remove the stroke effect entirely when no outline is wanted (do not set a stroke color at all)
- Use an opaque stroke color such as '#000000' or 'rgba(0,0,0,1)'
- Only set strokeColor when strokeWidth is greater than zero, with a validated opaque value
Example fix
// before
$image->text('hi', 0, 0, fn ($font) => $font
->color('#ffffff')
->stroke('transparent', 2)
);
// after - no stroke effect at all
$image->text('hi', 0, 0, fn ($font) => $font
->color('#ffffff')
); Defensive patterns
Strategy: validation
Validate before calling
// omit the stroke entirely when no outline is wanted
$callback = function ($font) use ($textColor, $strokeColor, $strokeWidth) {
$font->color($textColor);
if ($strokeWidth > 0 && isOpaqueHexColor($strokeColor)) {
$font->stroke($strokeColor, $strokeWidth);
}
};
$image->text($caption, $x, $y, $callback); Type guard
function isOpaqueHexColor(string $color): bool
{
return (bool) preg_match('/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i', $color);
} Try / catch
use Intervention\Image\Exceptions\StateException;
try {
$image->text($caption, $x, $y, $fontCallback);
} catch (StateException $e) {
throw new InvalidArgumentException('Invalid stroke config: ' . $e->getMessage(), 0, $e);
} Prevention
- Do not use 'transparent' as a way to disable the stroke - remove the stroke call
- Only set strokeColor when strokeWidth > 0
- Validate style presets against the opaque-color rule in unit tests
When it happens
Trigger: $image->text('label', $x, $y, fn ($font) => $font->color('fff')->stroke('transparent', 2)), or any stroke color with alpha 0 ('rgba(0,0,0,0)', 8-digit hex ending in 00) while strokeWidth > 0.
Common situations: Configurable text styles where an empty stroke color defaults to 'transparent'; conditionally disabling the stroke by setting a transparent stroke color instead of removing the effect; palette-driven designs that include a fully transparent variant.
Related errors
- The text color must be fully opaque when using the stroke ef
- The text color must be fully opaque when using the stroke ef
- The stroke color must be fully opaque
- No font file specified
- Failed query font metrics
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/058335d839c9e8ab.
Report an issue: GitHub.