{"record":{"id":"a115190bb45915d9","repo":"symfony/translation","slug":"translation-writer-was-not-able-to-create-directory-s","errorCode":null,"errorMessage":"Translation Writer was not able to create directory \"%s\".","messagePattern":"Translation Writer was not able to create directory \"(.+?)\"\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"Writer/TranslationWriter.php","lineNumber":65,"sourceCode":"    /**\n     * Writes translation from the catalogue according to the selected format.\n     *\n     * @param string $format  The format to use to dump the messages\n     * @param array  $options Options that are passed to the dumper\n     *\n     * @throws InvalidArgumentException\n     */\n    public function write(MessageCatalogue $catalogue, string $format, array $options = []): void\n    {\n        if (!isset($this->dumpers[$format])) {\n            throw new InvalidArgumentException(\\sprintf('There is no dumper associated with format \"%s\".', $format));\n        }\n\n        // get the right dumper\n        $dumper = $this->dumpers[$format];\n\n        if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0o777, true) && !is_dir($options['path'])) {\n            throw new RuntimeException(\\sprintf('Translation Writer was not able to create directory \"%s\".', $options['path']));\n        }\n\n        // save\n        $dumper->dump($catalogue, $options);\n    }\n}\n","sourceCodeStart":47,"sourceCodeEnd":72,"githubUrl":"https://github.com/symfony/translation/blob/ae9e8a51bc29780d63c7f9efd6005d7c875e100b/Writer/TranslationWriter.php#L47-L72","documentation":"When write() receives an options['path'], it tries @mkdir(path, 0777, true) if the directory does not exist. If creation fails (and the dir still doesn't exist), it throws this RuntimeException. @mkdir suppresses the PHP warning, so the exception is the only signal — typically a permissions problem on the parent directory.","triggerScenarios":"write($catalogue, $format, ['path' => '/some/nonexistent/dir']) where the directory cannot be created: read-only filesystem, missing parent-directory permissions, disk full, or path exists as a file.","commonSituations":"Dumping translations in CI containers with read-only workspaces; wrong path configured in translation extraction config; trying to write into vendor/ or a root-owned directory.","solutions":["Create the directory beforehand with correct permissions: mkdir -p <path>","Verify the parent directory is writable by the PHP process user","Check that the path is not an existing file","Use a writable path in your config/CI environment"],"exampleFix":"// before\n$writer->write($catalogue, 'xlf', ['path' => $config['output_dir']]);\n// after\n$dir = $config['output_dir'];\nif (!is_dir($dir) && !@mkdir($dir, 0777, true)) {\n    throw new RuntimeException(\"Cannot create output dir: $dir\");\n}\n$writer->write($catalogue, 'xlf', ['path' => $dir]);","handlingStrategy":"validation","validationCode":"if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) {\n    throw new \\RuntimeException(\"Output directory not writable: {$options['path']}\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    $writer->write($catalogue, $format, $options);\n} catch (\\RuntimeException $e) {\n    // handle directory creation failure: check permissions/disk space\n    throw new \\RuntimeException(\"Translation dump failed: \".$e->getMessage(), 0, $e);\n}","preventionTips":["Pre-create output directories with correct ownership in deployment/CI scripts","Verify writability with is_writable() before dumping","Ensure the path is a directory, not a file"],"tags":["php","filesystem","mkdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"ae9e8a51bc29780d63c7f9efd6005d7c875e100b","analyzedAt":"2026-09-15T22:29:15.305Z","contentChangedAt":"2026-09-15T22:29:15.305Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}