Intervention/image · error · ModifierException

Failed to apply ' . self::class . ', unable to draw text lin

Error message

Failed to apply ' . self::class . ', unable to draw text line

What it means

ModifierException from the Imagick text modifier: annotateImage() threw an ImageException while drawing a single line of text. The most common root cause is an unusable font - ImagickDraw silently accepts a bad font file and the failure only surfaces when annotation runs. The original exception is attached via getPrevious().

Source

Thrown at src/Drivers/Imagick/Modifiers/TextModifier.php:128

     * @throws ModifierException
     */
    private function maybeDrawTextline(
        FrameInterface $frame,
        Line $textline,
        ?ImagickDraw $draw = null,
        PointInterface $offset = new Point(),
    ): void {
        if ($draw instanceof ImagickDraw) {
            try {
                $result = $frame->native()->annotateImage(
                    $draw,
                    $textline->position()->x() + $offset->x(),
                    $textline->position()->y() + $offset->y(),
                    $this->font->angle(),
                    (string) $textline,
                );
            } catch (ImageException $e) {
                throw new ModifierException(
                    'Failed to apply ' . self::class . ', unable to draw text line',
                    previous: $e,
                );
            }

            if ($result === false) {
                throw new ModifierException(
                    'Failed to apply ' . self::class . ', unable to draw text line',
                );
            }
        }
    }

    /**
     * Return imagick font processor
     *
     * @throws DriverException
     * @throws StateException

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Verify the font path exists and is readable (is_file() + is_readable()) before calling text()
  2. Use an absolute path to the font file
  3. Test the font with ImageMagick directly or a raw Imagick script to confirm FreeType can load it
  4. Catch ModifierException and inspect getPrevious() for the underlying reason

Example fix

// before
$image->text('hello', 10, 50, fn ($font) => $font->filename('fonts/arial.ttf'));

// after
$fontPath = '/var/www/app/fonts/arial.ttf';
if (!is_readable($fontPath)) {
    throw new RuntimeException("Font not readable: {$fontPath}");
}
$image->text('hello', 10, 50, fn ($font) => $font->filename($fontPath));
Defensive patterns

Strategy: validation

Validate before calling

if (!is_string($fontPath) || !is_file($fontPath) || !is_readable($fontPath)) {
    throw new InvalidArgumentException("Font file missing or unreadable: {$fontPath}");
}
$image->text('hello', $x, $y, fn ($font) => $font->filename($fontPath));

Type guard

function isUsableFontFile(string $path): bool
{
    return is_file($path) && is_readable($path) && str_ends_with(strtolower($path), '.ttf');
}

Try / catch

use Intervention\Image\Exceptions\ModifierException;

try {
    $image->text($line, $x, $y, $fontCallback);
} catch (ModifierException $e) {
    $reason = $e->getPrevious()?->getMessage() ?? $e->getMessage();
    throw new RuntimeException("Text draw failed for font {$fontPath}: {$reason}", 0, $e);
}

Prevention

When it happens

Trigger: $image->text('hello', $x, $y, fn ($font) => $font->filename($fontPath)) where the font file does not exist, is unreadable (permissions, open_basedir), or is not a loadable TTF/OTF for ImageMagick's FreeType delegate; each text line is drawn individually so the throw happens per line.

Common situations: Relative font paths that resolve differently between CLI and web SAPI; font files outside the PHP open_basedir; corrupt or non-TrueType font files; servers missing the FreeType delegate in ImageMagick.

Related errors


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