{"record":{"id":"1a2ea1249921e5f2","repo":"guzzle/guzzle","slug":"unable-to-save-file-s","errorCode":null,"errorMessage":"Unable to save file %s","messagePattern":"Unable to save file (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Cookie/FileCookieJar.php","lineNumber":110,"sourceCode":"    {\n        $json = [];\n        /** @var SetCookie $cookie */\n        foreach ($this as $cookie) {\n            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {\n                $data = $cookie->toArray();\n                $data['HostOnly'] = $cookie->getHostOnly();\n                $json[] = $data;\n            }\n        }\n\n        try {\n            $jsonStr = \\json_encode($json, \\JSON_HEX_TAG | \\JSON_THROW_ON_ERROR);\n        } catch (\\JsonException $e) {\n            throw new \\RuntimeException('Unable to encode cookie data', 0, $e);\n        }\n\n        if (false === \\file_put_contents($filename, $jsonStr, \\LOCK_EX)) {\n            throw new \\RuntimeException(\\sprintf('Unable to save file %s', DiagnosticValue::escape($filename)));\n        }\n\n        // Best-effort: restrict the cookie file to the owner so persisted\n        // cookies are not world-readable.\n        @\\chmod($filename, 0600);\n    }\n\n    /**\n     * Load cookies from a JSON formatted file.\n     *\n     * Old cookies are kept unless overwritten by newly loaded ones.\n     * Cookie records are constructed before any are passed to setCookie().\n     *\n     * @param string $filename Cookie file to load.\n     *\n     * @throws \\RuntimeException if the file cannot be loaded or is invalid\n     */\n    public function load(string $filename): void","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/guzzle/guzzle/blob/d1cbca76970939a9c2ced55b1e25ea26f34fc773/src/Cookie/FileCookieJar.php#L92-L128","documentation":"save() calls file_put_contents($filename, $jsonStr, LOCK_EX) and treats a false return as a hard failure. The path is escaped with DiagnosticValue::escape so control bytes in the path cannot tamper with the exception message. Any IO-level write failure (missing directory, unwritable target, disk full, lock contention) lands here.","triggerScenarios":"Constructor path points at a directory that does not exist or is not writable by the PHP runtime user; the file is on a read-only filesystem; LOCK_EX could not be acquired; out of disk or inodes.","commonSituations":"Containerized deployments where the cookie path is on an unmounted volume; per-user directories that were never created; permissions reset by a deployment; PHP-FPM running as www-data while the target dir is owned by root.","solutions":["Ensure the parent directory exists and is writable: mkdir(dirname($path), 0700, true) before constructing the jar.","Verify the runtime user owns or can write the target file.","Check disk space and inode usage on the target filesystem.","Use an absolute path; confirm the path is not on a read-only mount."],"exampleFix":"// before\nnew FileCookieJar('/var/run/app/cookies.json');\n\n// after\n$path = '/var/run/app/cookies.json';\n@mkdir(dirname($path), 0700, true);\nnew FileCookieJar($path);","handlingStrategy":"validation","validationCode":"// Verify the directory is writable before constructing the jar.\nfunction ensureWritableFile(string $path): void {\n    $dir = \\dirname($path);\n    if (!\\is_dir($dir)) {\n        \\mkdir($dir, 0700, true);\n    }\n    if (!\\is_writable($dir)) {\n        throw new \\RuntimeException(\"Cookie dir not writable: {$dir}\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $jar = new FileCookieJar($path);\n    $jar->save($path);\n} catch (\\RuntimeException $e) {\n    // IO failure; degrade gracefully (e.g. fall back to in-memory jar)\n}","preventionTips":["Pre-create the cookie directory with mkdir(..., 0700, true).","Confirm the PHP runtime user owns or can write the target path.","Use absolute paths and check disk space on the target filesystem."],"tags":["cookies","file-io","permissions","persistence"],"backgroundTag":null,"analyzedSha":"d1cbca76970939a9c2ced55b1e25ea26f34fc773","analyzedAt":"2026-08-06T00:37:27.795Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}