{"record":{"id":"75c90d56c3e50f97","repo":"GoogleChrome/lighthouse","slug":"output-path-value-cannot-be-written-to","errorCode":null,"errorMessage":"--output-path (${value}) cannot be written to","messagePattern":"--output-path \\((.+?)\\) cannot be written to","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/cli-flags.js","lineNumber":416,"sourceCode":"    if (!outputTypes.includes(str)) {\n      throw new Error(`\"${str}\" is not a valid 'output' value. ` + errorHint);\n    }\n    return true;\n  });\n\n  return validValues;\n}\n\n/**\n * Verifies outputPath is something we can actually write to.\n * @param {unknown=} value\n * @return {string=}\n */\nfunction coerceOutputPath(value) {\n  if (value === undefined) return;\n\n  if (typeof value !== 'string' || !value || !fs.existsSync(path.dirname(value))) {\n    throw new Error(`--output-path (${value}) cannot be written to`);\n  }\n\n  return value;\n}\n\n/**\n * Verifies value is a string, then coerces type to LH.Locale for convenience. However, don't\n * allowlist specific locales. Why? So we can support the user who requests 'es-MX' (unsupported)\n * and we'll fall back to 'es' (supported).\n * @param {unknown} value\n * @return {LH.Locale|undefined}\n */\nfunction coerceLocale(value) {\n  if (value === undefined) return;\n\n  if (typeof value !== 'string') throw new Error(`Invalid value: Argument 'locale' must be a string`);\n  return /** @type {LH.Locale} */ (value);\n}","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/cli/cli-flags.js#L398-L434","documentation":"The --output-path flag specifies where Lighthouse writes its report. coerceOutputPath validates that the value is a non-empty string and that the parent directory (path.dirname) exists on the filesystem. This prevents Lighthouse from failing later during the write phase.","triggerScenarios":"Passing --output-path with a value that is undefined (but somehow not caught earlier), an empty string, or a path whose parent directory does not exist. For example: --output-path=/nonexistent/dir/report.json where /nonexistent/dir does not exist.","commonSituations":"Typo in the directory path; pointing to a directory that hasn't been created yet; relative path resolved from an unexpected working directory; trailing slash causing dirname to resolve unexpectedly.","solutions":["Create the target directory first: mkdir -p ./reports && lighthouse --output-path=./reports/report.json","Verify the path is correct and the parent directory exists: ls -la $(dirname your/path)","Use stdout to avoid filesystem issues: --output-path=stdout (valid for JSON output)"],"exampleFix":"# before\nlighthouse --output-path=/tmp/nonexistent/report.json https://example.com\n# after\nmkdir -p /tmp/reports && lighthouse --output-path=/tmp/reports/report.json https://example.com","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nconst path = require('path');\nfunction validateOutputPath(outputPath) {\n  if (typeof outputPath !== 'string' || !outputPath) {\n    throw new Error('outputPath must be a non-empty string');\n  }\n  const dir = path.dirname(outputPath);\n  if (!fs.existsSync(dir)) {\n    throw new Error(`Parent directory does not exist: ${dir}`);\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always mkdir -p the output directory before running Lighthouse","Use absolute paths to avoid working-directory ambiguity","For JSON output, consider --output-path=stdout to avoid filesystem issues entirely"],"tags":["cli","validation","filesystem","output"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}