{"record":{"id":"1397c9b598c914d1","repo":"PHPOffice/PhpSpreadsheet","slug":"unable-to-get-contents-of-filename","errorCode":null,"errorMessage":"Unable to get contents of $filename","messagePattern":"Unable to get contents of \\$filename","errorType":"exception","errorClass":"ReaderException","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Csv.php","lineNumber":313,"sourceCode":"            if ($encoding !== '') {\n                $this->inputEncoding = $encoding;\n            }\n        }\n        if ($this->inputEncoding === self::GUESS_ENCODING) {\n            $this->inputEncoding = self::guessEncoding($filename, $this->fallbackEncoding);\n        }\n        $this->openFile($filename);\n        if ($this->inputEncoding !== 'UTF-8') {\n            $this->convertNonUtf8($filename);\n        }\n    }\n\n    protected function convertNonUtf8(string $filename): void\n    {\n        fclose($this->fileHandle);\n        $entireFile = file_get_contents($filename);\n        if ($entireFile === false) {\n            throw new ReaderException(\"Unable to get contents of $filename\"); // @codeCoverageIgnore\n        }\n        $fileHandle = fopen('php://memory', 'r+b');\n        if ($fileHandle === false) {\n            throw new ReaderException('Unable to open php://memory'); // @codeCoverageIgnore\n        }\n        $this->fileHandle = $fileHandle;\n        $data = StringHelper::convertEncoding($entireFile, 'UTF-8', $this->inputEncoding);\n        fwrite($this->fileHandle, $data);\n        $this->skipBOM();\n    }\n\n    public function setTestAutoDetect(bool $value): self\n    {\n        $this->testAutodetect = $value;\n\n        return $this;\n    }\n","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Csv.php#L295-L331","documentation":"When the Csv reader's input encoding is not UTF-8, convertNonUtf8() re-reads the entire file with file_get_contents() to re-encode it. This exception fires if that read returns false — an environmental failure (the file vanished or became unreadable between the earlier fopen and this read), which is why upstream marks it @codeCoverageIgnore.","triggerScenarios":"The file is deleted or its permissions change mid-request (temp-dir cleanup race); a 2GB+ file on a 32-bit PHP build where size handling fails; filesystem faults while the import runs.","commonSituations":"Long-running queue jobs parsing uploads stored in an aggressively cleaned tmp directory; files larger than PHP's integer handling on 32-bit deployments.","solutions":["Copy the upload to a temp file you control before loading, and load that copy","Ensure nothing deletes or mutates the file while the reader runs (adjust tmp retention)","Run 64-bit PHP for very large files"],"exampleFix":"// before\n$spreadsheet = (new Csv())->load('/tmp/queue/incoming.csv'); // cleaner may unlink mid-load\n\n// after\n$stable = tempnam(sys_get_temp_dir(), 'csv');\ncopy($incomingPath, $stable);\n$spreadsheet = (new Csv())->load($stable);\nunlink($stable);","handlingStrategy":"validation","validationCode":"if (!is_readable($filename)) {\n    throw new RuntimeException(\"Input vanished or unreadable: $filename\");\n}\n$stable = tempnam(sys_get_temp_dir(), 'csv');\ncopy($filename, $stable); // decouple from cleanup races\n$spreadsheet = (new Csv())->load($stable);\nunlink($stable);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Parse a private copy of transient files (uploads, tmp) rather than the original path","Keep tmp-retention longer than your max job runtime","Run 64-bit PHP builds for very large file imports"],"tags":["csv","encoding","race-condition","environment"],"backgroundTag":"file-read-failure","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}