{"record":{"id":"a6e45f2596bee18c","repo":"symfony/symfony","slug":"the-configured-log-file-s-is-not-writeable","errorCode":null,"errorMessage":"The configured log file \"%s\" is not writeable.","messagePattern":"The configured log file \"(.+?)\" is not writeable\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php","lineNumber":309,"sourceCode":"        if (!self::hasColorSupport()) {\n            return $str;\n        }\n\n        $color = $red ? '41;37' : '43;30';\n\n        return \"\\x1B[{$color}m{$str}\\x1B[0m\";\n    }\n\n    /**\n     * @param string[] $groups\n     */\n    private function displayDeprecations(array $groups, Configuration $configuration): void\n    {\n        $cmp = static fn ($a, $b) => $b->count() - $a->count();\n\n        if ($configuration->shouldWriteToLogFile()) {\n            if (false === $handle = @fopen($file = $configuration->getLogFile(), 'a')) {\n                throw new \\InvalidArgumentException(\\sprintf('The configured log file \"%s\" is not writeable.', $file));\n            }\n        } else {\n            $handle = fopen('php://output', 'w');\n        }\n\n        foreach ($groups as $group) {\n            if ($this->deprecationGroups[$group]->count()) {\n                $deprecationGroupMessage = \\sprintf(\n                    '%s deprecation notices (%d)',\n                    \\in_array($group, ['direct', 'indirect', 'self'], true) ? \"Remaining $group\" : ucfirst($group),\n                    $this->deprecationGroups[$group]->count()\n                );\n                if ($configuration->shouldWriteToLogFile()) {\n                    fwrite($handle, \"\\n$deprecationGroupMessage\\n\");\n                } else {\n                    fwrite($handle, \"\\n\".self::colorize($deprecationGroupMessage, 'legacy' !== $group && 'indirect' !== $group).\"\\n\");\n                }\n","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/symfony/symfony/blob/698e28026c22cf35d032cdb6e800db48b1535790/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php#L291-L327","documentation":"Thrown during DeprecationErrorHandler::displayDeprecations (InvalidArgumentException, line 309) at test-suite shutdown. When SYMFONY_DEPRECATIONS_HELPER contains a 'logFile' query parameter, the handler tries fopen($logFile, 'a'); if that returns false (file/dir not writable, path doesn't exist, permissions), it throws with the offending path. This fires at shutdown, so it appears after the test run rather than at boot.","triggerScenarios":"Setting SYMFONY_DEPRECATIONS_HELPER=max[total]=0&logFile=/var/log/symfony-deprecations.log where /var/log isn't writable by the test runner, or the logFile path's parent directory doesn't exist. Triggered when displayDeprecations() runs (shutdown handler) and the deprecation report is configured for file output.","commonSituations":"CI running as an unprivileged user pointing logFile at a system dir; relative path resolved against an unexpected cwd; container where the mounted volume is read-only; path with a missing intermediate directory (fopen can't create dirs).","solutions":["Point logFile at a directory the test process can write (e.g. var/log/, build/logs/, or %kernel.cache_dir%).","Create the parent directory and fix permissions: mkdir -p var/log && chmod a+w var/log.","Use an absolute path you control; remove logFile from SYMFONY_DEPRECATIONS_HELPER to fall back to stdout (php://output)."],"exampleFix":"# before\nSYMFONY_DEPRECATIONS_HELPER=max[total]=0&logFile=/var/log/deprecations.log\n\n# after (writable project dir, ensure it exists)\nmkdir -p var/log\nSYMFONY_DEPRECATIONS_HELPER=max[total]=0&logFile=%kernel.project_dir%/var/log/deprecations.log","handlingStrategy":"validation","validationCode":"$logFile = $_ENV['SYMFONY_DEPRECATIONS_HELPER_LOG'] ?? null;\nif ($logFile !== null) {\n    $dir = dirname($logFile);\n    if (!is_dir($dir) || !is_writable($dir)) {\n        throw new \\RuntimeException('logFile dir not writable: '.$dir);\n    }\n}","typeGuard":"function logFileIsWritable(?string $path): bool {\n    if ($path === null) return true;\n    $dir = realpath(dirname($path));\n    return $dir !== false && is_dir($dir) && is_writable($dir);\n}","tryCatchPattern":"try {\n    // run phpunit with logFile set\n} catch (\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'is not writeable')) {\n        // fall back to stdout by removing logFile from SYMFONY_DEPRECATIONS_HELPER\n        putenv('SYMFONY_DEPRECATIONS_HELPER='.preg_replace('/&?logFile=[^&]*/', '', getenv('SYMFONY_DEPRECATIONS_HELPER')));\n    }\n    throw $e;\n}","preventionTips":["Use a project-local dir (var/log) created by your build, not a system path.","Add a CI step that mkdir -p the log dir before phpunit.","Verify is_writable(dirname($logFile)) at boot, not at shutdown."],"tags":["phpunit-bridge","deprecations","filesystem","ci","permissions"],"analyzedSha":"698e28026c22cf35d032cdb6e800db48b1535790","analyzedAt":"2026-08-06T23:40:49.025Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}