{"record":{"id":"e99cc8a1a6a932dc","repo":"Intervention/image","slug":"unable-to-analyze-image-colors","errorCode":null,"errorMessage":"Unable to analyze image colors","messagePattern":"Unable to analyze image colors","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\AnalyzerException","httpStatus":null,"severity":"error","filePath":"src/Analyzers/DominantPaletteAnalyzer.php","lineNumber":92,"sourceCode":"\n        $palette = new Palette();\n        $minClusterSize = (count($points) * self::MIN_CLUSTER_SIZE_PERCENT) / 100;\n        $colorspace = $image->colorspace();\n\n        foreach ($clusters as $cluster) {\n            // filter out very small clusters\n            if ($cluster['size'] < $minClusterSize) {\n                continue;\n            }\n\n            try {\n                $palette->addColor(\n                    // convert centroids back to original colorspace\n                    (new OklabColor(...$cluster['centroid']))->toColorspace($colorspace),\n                    $cluster['size'],\n                );\n            } catch (InvalidArgumentException $e) {\n                throw new AnalyzerException('Unable to analyze image colors', previous: $e);\n            }\n        }\n\n        // palette has already a limit of k and is already sorted by cluster size\n        return $palette;\n    }\n\n    /**\n     * Transform color to flattened oklab color channel triples which can be used for clustering.\n     *\n     * @param Generator<ColorInterface> $colors\n     * @throws AnalyzerException\n     * @return array<array{float, float, float}>\n     */\n    private function clusterableColors(Generator $colors): array\n    {\n        $clusterable = [];\n        foreach ($colors as $color) {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Analyzers/DominantPaletteAnalyzer.php#L74-L110","documentation":"This FileNotReadableException is thrown by filePathFromSplFileInfoOrFail() when everything else checks out (directory exists, file exists, is a regular file, directory is readable) but is_readable($path) on the file itself returns false. The PHP process cannot open the file for reading, typically due to file ownership/mode.","triggerScenarios":"ImageManager::read(new SplFileInfo($path)) on a file with mode 0600 owned by another user; files created by root during deployment that the web server user must later read; attachments uploaded through a different service with restrictive umask (0066 result); files on a mounted share with ACLs denying the PHP user.","commonSituations":"Mixed CLI/web workflows: artisan commands or cron jobs running as root produce files the php-fpm user cannot read; SCP/SFTP uploads defaulting to 0600; NAS/NFS mounts with mismatched UIDs; shared hosting where the account user differs from the PHP process user.","solutions":["Make the file readable by the PHP user: chmod 644 <file> (or chown it to the PHP-FPM user)","Fix the producer side: set a sane umask or explicit chmod right after the file is created/written","Verify with: sudo -u www-data test -r /path/to/file && echo ok"],"exampleFix":"// before: file written by root with 0600, web server cannot read it\nfile_put_contents($path, $blob); // umask 0077\n\n// after: ensure group/world readability\nfile_put_contents($path, $blob);\nchmod($path, 0644);","handlingStrategy":"validation","validationCode":"if (!is_readable($splFileInfo->getPathname())) {\n    // cannot be read by current PHP user\n    throw new \\RuntimeException('Image file unreadable, check ownership/mode: ' . $splFileInfo->getPathname());\n}\n$image = $manager->read($splFileInfo);","typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\FileNotReadableException;\n\ntry {\n    $image = $manager->read($file);\n} catch (FileNotReadableException $e) {\n    if (str_contains($e->getMessage(), 'is not readable')) {\n        chmod($file->getPathname(), 0644); // attempt repair, then retry once\n        $image = $manager->read($file);\n    }\n}","preventionTips":["Set an explicit umask (0022) in workers that create files consumed by the web server","chmod 0644 immediately after writing files that other processes must read","For NFS/shared mounts, align UIDs or use ACLs (setfacl -m u:www-data:r)"],"tags":["permissions","file-not-readable","splfileinfo","filesystem","intervention-image"],"backgroundTag":"file-permission-denied","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}