{"record":{"id":"533dc5594557e6a4","repo":"phacility/phabricator","slug":"failed-to-open-output-file-s-for-writing","errorCode":null,"errorMessage":"Failed to open output file \"%s\" for writing.","messagePattern":"Failed to open output file \"(.+?)\" for writing\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php","lineNumber":139,"sourceCode":"      $lines = new LinesOfALargeExecFuture($future);\n    } else {\n      $lines = new LinesOfALargeFile($input);\n    }\n\n    if ($output_file === null) {\n      $file = fopen('php://stdout', 'wb');\n      $output_name = pht('stdout');\n    } else {\n      if ($is_compress) {\n        $file = gzopen($output_file, 'wb');\n      } else {\n        $file = fopen($output_file, 'wb');\n      }\n      $output_name = $output_file;\n    }\n\n    if (!$file) {\n      throw new Exception(\n        pht(\n          'Failed to open output file \"%s\" for writing.',\n          $output_name));\n    }\n\n    $name_pattern = preg_quote($from, '@');\n\n    $patterns = array(\n      'use' => '@^(USE `)('.$name_pattern.')(_.*)$@',\n      'create' => '@^(CREATE DATABASE /\\*.*?\\*/ `)('.$name_pattern.')(_.*)$@',\n    );\n\n    $found = array_fill_keys(array_keys($patterns), 0);\n\n    try {\n      $matches = null;\n      foreach ($lines as $line) {\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementRenamespaceWorkflow.php#L121-L157","documentation":"Renamespace could not open its destination for writing: fopen($output_file, 'wb') or, with `--compress`, gzopen returned false, so the workflow throws before writing anything. Typical causes are a missing parent directory, permission denied, a path naming a directory, or a read-only filesystem. A generic Exception is thrown and the command aborts; the handler then tries to remove the output path, which is harmless at this stage.","triggerScenarios":"`--output /missing/dir/out.sql` where the parent directory does not exist; an unwritable directory (permissions or ownership); `--output` naming a directory; with `--compress`, an environment where gzopen fails.","commonSituations":"Outputting into a directory that was never created (for example /srv/exports); running as a user without write access to a root-owned path; typos in long absolute paths; SELinux denying writes to the target context.","solutions":["Create and permission the parent directory: `mkdir -p $(dirname $OUT)`, then retry.","Verify writability as the same user (`touch $OUT`); if it fails, fix ownership or write under /tmp.","Use an absolute path to rule out cwd and relative-path confusion.","If gzopen fails with --compress, drop --compress and gzip afterwards: pipe stdout through `gzip -c > out.sql.gz`."],"exampleFix":"# before\n./bin/storage renamespace --live --from a --to b --output /srv/exports/out.sql\n\n# after\nmkdir -p /srv/exports && chown $(id -un) /srv/exports\n./bin/storage renamespace --live --from a --to b --output /srv/exports/out.sql","handlingStrategy":"validation","validationCode":"out_dir=$(dirname \"$OUT\")\n[ -d \"$out_dir\" ] || { echo \"missing directory: $out_dir\" >&2; exit 2; }\n[ -w \"$out_dir\" ] || { echo \"not writable: $out_dir\" >&2; exit 2; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pre-create output directories as part of script setup (mkdir -p).","Verify write access as the invoking user with a touch test before long dumps run."],"tags":["phabricator","bin-storage","renamespace","file-io","permissions","filesystem"],"backgroundTag":"cannot-open-output-file","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}