{"record":{"id":"2fb1ef3be70621ab","repo":"Intervention/image","slug":"the-text-color-must-be-fully-opaque-when-using-the-2fb1ef","errorCode":null,"errorMessage":"The text color must be fully opaque when using the stroke effect","messagePattern":"The text color must be fully opaque when using the stroke effect","errorType":"exception","errorClass":"StateException","httpStatus":null,"severity":"error","filePath":"src/Modifiers/TextModifier.php","lineNumber":42,"sourceCode":"        //\n    }\n\n    /**\n     * Decode text color.\n     *\n     * The text outline effect is drawn with a trick by plotting additional text\n     * under the actual text with an offset in the color of the outline effect.\n     * For this reason, no colors with transparency can be used for the text\n     * color or the color of the stroke effect, as this would be superimposed.\n     *\n     * @throws StateException\n     */\n    protected function textColor(): ColorInterface\n    {\n        $color = $this->driver()->decodeColor($this->font->color());\n\n        if ($this->font->hasStrokeEffect() && $color->isTransparent()) {\n            throw new StateException(\n                'The text color must be fully opaque when using the stroke effect',\n            );\n        }\n\n        return $color;\n    }\n\n    /**\n     * Decode outline stroke color.\n     *\n     * @throws StateException\n     */\n    protected function strokeColor(): ColorInterface\n    {\n        $color = $this->driver()->decodeColor($this->font->strokeColor());\n\n        if ($color->isTransparent()) {\n            throw new StateException(","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Modifiers/TextModifier.php#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n$image->text('Watermark', 10, 10, function ($font) {\n    $font->color('transparent');\n    $font->strokeColor('ff0000');\n    $font->strokeWidth(2);\n});\n\n// after\n$image->text('Watermark', 10, 10, function ($font) {\n    $font->color('ffffff');\n    $font->strokeColor('ff0000');\n    $font->strokeWidth(2);\n});","handlingStrategy":"validation","validationCode":"use Intervention\\Image\\Colors\\Rgb\\Color;\n\n// Before rendering stroked text, ensure the fill is opaque\n$color = $font->color();\n$isTransparent = $color instanceof Color ? $color->isTransparent() : $color === 'transparent';\n\nif ($font->hasStrokeEffect() && $isTransparent) {\n    $font->color('ffffff'); // opaque fill\n}\n\n$image->text('caption', 10, 10, $font);","typeGuard":"function fontAllowsStrokeEffect($font): bool\n{\n    // stroke effect requires an opaque text color\n    $color = $font->color();\n\n    return !($font->hasStrokeEffect()\n        && ($color === 'transparent' || str_starts_with((string) $color, 'rgba')));\n}\n\n// exact check requires decoding the color through the driver; simplest is to avoid transparent fills on stroked text","tryCatchPattern":"use Intervention\\Image\\Exceptions\\StateException;\n\ntry {\n    $image->text('Watermark', 10, 10, $font);\n} catch (StateException $e) {\n    // message: 'The text color must be fully opaque when using the stroke effect'\n    $font->color('ffffff');\n    $image->text('Watermark', 10, 10, $font);\n}","preventionTips":["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"],"tags":["text","font","stroke","color","state","intervention-image"],"backgroundTag":"invalid-color-value","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}