Intervention/image · error · StateException
The text color must be fully opaque when using the stroke ef
Error message
The text color must be fully opaque when using the stroke effect
What it means
When drawing text with a stroke/outline effect, the driver renders the outline by plotting the same text multiple times in the stroke color underneath the actual text (see TextModifier.php:30-33). A fully transparent text color would let that underlaid stroke bleed through, so the library throws StateException when the font has a stroke effect (strokeWidth > 0) and the decoded text color is transparent. This is a state check, not a syntax check: each value is fine on its own, only the combination is invalid.
Source
Thrown at src/Modifiers/TextModifier.php:42
//
}
/**
* Decode text color.
*
* The text outline effect is drawn with a trick by plotting additional text
* under the actual text with an offset in the color of the outline effect.
* For this reason, no colors with transparency can be used for the text
* color or the color of the stroke effect, as this would be superimposed.
*
* @throws StateException
*/
protected function textColor(): ColorInterface
{
$color = $this->driver()->decodeColor($this->font->color());
if ($this->font->hasStrokeEffect() && $color->isTransparent()) {
throw new StateException(
'The text color must be fully opaque when using the stroke effect',
);
}
return $color;
}
/**
* Decode outline stroke color.
*
* @throws StateException
*/
protected function strokeColor(): ColorInterface
{
$color = $this->driver()->decodeColor($this->font->strokeColor());
if ($color->isTransparent()) {
throw new StateException(View on GitHub (pinned to 5598b9e397)
Solutions
- Use a fully opaque text color (e.g. 'ffffff') together with the stroke effect
- If you want outline-only text, set the fill to the background color instead of transparent
- Drop the stroke effect when the fill must stay transparent: set strokeWidth to 0
Example fix
// before
$image->text('Watermark', 10, 10, function ($font) {
$font->color('transparent');
$font->strokeColor('ff0000');
$font->strokeWidth(2);
});
// after
$image->text('Watermark', 10, 10, function ($font) {
$font->color('ffffff');
$font->strokeColor('ff0000');
$font->strokeWidth(2);
}); Defensive patterns
Strategy: validation
Validate before calling
use Intervention\Image\Colors\Rgb\Color;
// Before rendering stroked text, ensure the fill is opaque
$color = $font->color();
$isTransparent = $color instanceof Color ? $color->isTransparent() : $color === 'transparent';
if ($font->hasStrokeEffect() && $isTransparent) {
$font->color('ffffff'); // opaque fill
}
$image->text('caption', 10, 10, $font); Type guard
function fontAllowsStrokeEffect($font): bool
{
// stroke effect requires an opaque text color
$color = $font->color();
return !($font->hasStrokeEffect()
&& ($color === 'transparent' || str_starts_with((string) $color, 'rgba')));
}
// exact check requires decoding the color through the driver; simplest is to avoid transparent fills on stroked text Try / catch
use Intervention\Image\Exceptions\StateException;
try {
$image->text('Watermark', 10, 10, $font);
} catch (StateException $e) {
// message: 'The text color must be fully opaque when using the stroke effect'
$font->color('ffffff');
$image->text('Watermark', 10, 10, $font);
} Prevention
- Never combine strokeWidth > 0 with a transparent fill color
- Store watermark styles as tested presets instead of assembling colors at runtime
- An outline-only look is achieved with an opaque fill matching the background, not a transparent fill
- Check $font->hasStrokeEffect() before applying dynamic/theme colors
When it happens
Trigger: Combining $font->strokeWidth(2) (or ->strokeEffect()) with $font->color('transparent') or $font->color('rgba(0, 0, 0, 0)') and then calling $image->text('...', x, y, fn($font) => ...). It fires when the driver decodes colors during text rendering, not at font configuration time.
Common situations: Attempting an 'outline only' caption by making the fill transparent; theme configs that set a transparent text color for watermarks and later add a stroke width; alpha values computed dynamically (e.g. from opacity 0) reused for stroked text.
Related errors
- The stroke color must be fully opaque
- The text color must be fully opaque when using the stroke ef
- The stroke color must be fully opaque
- Unable to parse RGB color from input "{input}"
- No font file specified
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/2fb1ef3be70621ab.
Report an issue: GitHub.