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

  1. Use a fully opaque text color (e.g. 'ffffff') together with the stroke effect
  2. If you want outline-only text, set the fill to the background color instead of transparent
  3. 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

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


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