crewAIInc/crewAI · error · ProcessingDependencyError

Pillow is required for image optimization

Error message

Pillow is required for image optimization

What it means

optimize_image() lazily imports PIL and raises ProcessingDependencyError('Pillow is required for image optimization') with dependency='Pillow' when Pillow is missing. It runs when a current image exceeds target_size_bytes and must be recompressed (quality search between initial_quality and min_quality), so the error only fires for images that genuinely need shrinking.

Source

Thrown at lib/crewai-files/src/crewai_files/processing/transformers.py:109

    Uses iterative quality reduction to achieve target size.

    Args:
        file: The image file to optimize.
        target_size_bytes: Target maximum file size in bytes.
        min_quality: Minimum quality to use (prevents excessive degradation).
        initial_quality: Starting quality for optimization.

    Returns:
        A new ImageFile with the optimized image data.

    Raises:
        ProcessingDependencyError: If Pillow is not installed.
    """
    try:
        from PIL import Image
    except ImportError as e:
        raise ProcessingDependencyError(
            "Pillow is required for image optimization",
            dependency="Pillow",
            install_command="pip install Pillow",
        ) from e

    content = file.read()
    current_size = len(content)

    if current_size <= target_size_bytes:
        return file

    with Image.open(io.BytesIO(content)) as img:
        if img.mode in ("RGBA", "LA", "P"):
            img = img.convert("RGB")  # type: ignore[assignment]
            output_format = "JPEG"
        else:
            output_format = img.format or "JPEG"
            if output_format.upper() not in ("JPEG", "JPG"):

View on GitHub (pinned to 754d7323be)

Solutions

  1. Install Pillow: pip install Pillow.
  2. Add Pillow to the deployment image (Dockerfile: RUN pip install Pillow) or use a base image that includes it.
  3. Guard with a runtime check at startup (importlib.util.find_spec('PIL')) so the failure surfaces during deploy, not mid-request.
  4. If Pillow truly cannot be installed, pre-compress images before they reach the processor.

Example fix

# before
# no Pillow installed; image is 8MB, target 1MB
new_img = optimize_image(file, target_size_bytes=1_000_000)  # ProcessingDependencyError

# after
# shell: pip install Pillow
new_img = optimize_image(file, target_size_bytes=1_000_000)
Defensive patterns

Strategy: validation

Validate before calling

import importlib.util

if importlib.util.find_spec("PIL") is None:
    raise RuntimeError("image optimization requires Pillow: pip install Pillow")

Try / catch

from crewai_files.processing.exceptions import ProcessingDependencyError

try:
    out = optimize_image(file, target_size_bytes)
except ProcessingDependencyError as e:
    if e.dependency == "Pillow":
        out = file  # accept oversized file or reject upstream, but log it
        logger.warning("Pillow missing; %s not optimized", file.filename)
    else:
        raise

Prevention

When it happens

Trigger: AUTO-mode processing (or direct optimize_image call) on an image whose byte size exceeds target_size_bytes, in an environment without Pillow installed. Small images return early and never trigger it.

Common situations: Deploying to a container built from a minimal base after developing locally where Pillow was present; adding size constraints (max_size_bytes) for the first time, which activates the optimize path in production; team installs differ because Pillow is an optional dependency.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/b03048cdb4bcc262. Report an issue: GitHub.