{"record":{"id":"b03048cdb4bcc262","repo":"crewAIInc/crewAI","slug":"pillow-is-required-for-image-optimization","errorCode":null,"errorMessage":"Pillow is required for image optimization","messagePattern":"Pillow is required for image optimization","errorType":"exception","errorClass":"ProcessingDependencyError","httpStatus":null,"severity":"error","filePath":"lib/crewai-files/src/crewai_files/processing/transformers.py","lineNumber":109,"sourceCode":"\n    Uses iterative quality reduction to achieve target size.\n\n    Args:\n        file: The image file to optimize.\n        target_size_bytes: Target maximum file size in bytes.\n        min_quality: Minimum quality to use (prevents excessive degradation).\n        initial_quality: Starting quality for optimization.\n\n    Returns:\n        A new ImageFile with the optimized image data.\n\n    Raises:\n        ProcessingDependencyError: If Pillow is not installed.\n    \"\"\"\n    try:\n        from PIL import Image\n    except ImportError as e:\n        raise ProcessingDependencyError(\n            \"Pillow is required for image optimization\",\n            dependency=\"Pillow\",\n            install_command=\"pip install Pillow\",\n        ) from e\n\n    content = file.read()\n    current_size = len(content)\n\n    if current_size <= target_size_bytes:\n        return file\n\n    with Image.open(io.BytesIO(content)) as img:\n        if img.mode in (\"RGBA\", \"LA\", \"P\"):\n            img = img.convert(\"RGB\")  # type: ignore[assignment]\n            output_format = \"JPEG\"\n        else:\n            output_format = img.format or \"JPEG\"\n            if output_format.upper() not in (\"JPEG\", \"JPG\"):","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-files/src/crewai_files/processing/transformers.py#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Install Pillow: pip install Pillow.","Add Pillow to the deployment image (Dockerfile: RUN pip install Pillow) or use a base image that includes it.","Guard with a runtime check at startup (importlib.util.find_spec('PIL')) so the failure surfaces during deploy, not mid-request.","If Pillow truly cannot be installed, pre-compress images before they reach the processor."],"exampleFix":"# before\n# no Pillow installed; image is 8MB, target 1MB\nnew_img = optimize_image(file, target_size_bytes=1_000_000)  # ProcessingDependencyError\n\n# after\n# shell: pip install Pillow\nnew_img = optimize_image(file, target_size_bytes=1_000_000)","handlingStrategy":"validation","validationCode":"import importlib.util\n\nif importlib.util.find_spec(\"PIL\") is None:\n    raise RuntimeError(\"image optimization requires Pillow: pip install Pillow\")","typeGuard":null,"tryCatchPattern":"from crewai_files.processing.exceptions import ProcessingDependencyError\n\ntry:\n    out = optimize_image(file, target_size_bytes)\nexcept ProcessingDependencyError as e:\n    if e.dependency == \"Pillow\":\n        out = file  # accept oversized file or reject upstream, but log it\n        logger.warning(\"Pillow missing; %s not optimized\", file.filename)\n    else:\n        raise","preventionTips":["Install Pillow in every environment that sets size constraints on images.","Fail fast on missing optional deps at deploy time instead of mid-request.","Keep dev and prod dependency sets identical (lockfile)."],"tags":["pillow","dependency","image","compression","optional-dependency"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}