{"record":{"id":"ca23b52bd88e9eb3","repo":"apple/pkl","slug":"i-o-error-writing-path","errorCode":null,"errorMessage":"I/O error writing `$path`.","messagePattern":"I/O error writing `\\$path`\\.","errorType":"exception","errorClass":"DocGeneratorBugException","httpStatus":null,"severity":"error","filePath":"pkl-doc/src/main/kotlin/org/pkl/doc/PackageDataGenerator.kt","lineNumber":284,"sourceCode":"    pkg.docPackageInfo.sourceCode,\n    pkg.docPackageInfo.sourceCodeUrlScheme,\n    pkg.docPackageInfo.dependencies.map { DependencyData(PackageRef(it.name, it.uri, it.version)) },\n    pkg.docModules.mapNotNull { if (it.isUnlisted) null else ModuleData(pkg, it) },\n  )\n\n  fun write(path: Path) {\n    val jsonStr =\n      try {\n        json.encodeToString(this)\n      } catch (e: SerializationException) {\n        throw DocGeneratorBugException(\"Error serializing `$path`.\", e)\n      }\n\n    try {\n      path.createParentDirectories()\n      path.writer().use { it.write(jsonStr) }\n    } catch (e: IOException) {\n      throw DocGeneratorBugException(\"I/O error writing `$path`.\", e)\n    }\n  }\n}\n\n/** A package depended upon by [PackageData]. */\n@Serializable\ninternal class DependencyData(\n  /** The ref of the depended-on package. */\n  val ref: PackageRef\n)\n\n/** Persisted data for a module. */\n@Serializable\ninternal class ModuleData(\n  /** The ref of this module. */\n  val ref: ModuleRef,\n\n  /** The first paragraph of the overview documentation for this module. */","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-doc/src/main/kotlin/org/pkl/doc/PackageDataGenerator.kt#L266-L302","documentation":"PackageDataGenerator.write serializes package data to JSON and writes it to disk. It wraps any IOException from creating parent directories or writing the file into a DocGeneratorBugException, since a failure here is treated as a doc-generator bug rather than expected user error. The path is shown in the message with the underlying cause attached.","triggerScenarios":"Calling PackageDataGenerator.write when the output path's parent directories cannot be created, the path is not writable, the disk is full, or the filesystem rejects the write (permission denied, read-only volume).","commonSituations":"Running `pkl doc` generation into a directory the user lacks write permission for, outputting to a read-only CI workspace, or a disk-space/IO failure mid-write.","solutions":["Check write permissions on the target output directory and its parent path.","Verify the output path exists and is not a directory; free disk space if low.","Run the generator with a user account that owns the output directory.","Inspect the wrapped cause exception for the exact OS-level IO failure."],"exampleFix":"// before\npath.writer().use { it.write(jsonStr) } // IOException on read-only dir\n// after\nrequire(path.parent.isDirectory && path.parent.canWrite()) { \"Cannot write to ${path.parent}\" }\npath.writer().use { it.write(jsonStr) }","handlingStrategy":"try-catch","validationCode":"val out = File(\"build/docs/pkl\")\ncheck(out.isDirectory || out.mkdirs()) { \"Cannot create output dir\" }\ncheck(out.canWrite()) { \"Output dir not writable\" }","typeGuard":"fun isWritableDir(p: Path) = p.isDirectory() && java.nio.file.Files.isWritable(p)","tryCatchPattern":"try { generator.write() } catch (e: DocGeneratorBugException) { logger.error(\"Doc output write failed: ${e.message}\", e.cause) }","preventionTips":["Verify output directory permissions before doc generation","Run generation as the workspace owner in CI","Monitor disk space on build agents","Avoid writing to network/read-only mounts"],"tags":["io","file-write","kotlin"],"backgroundTag":"file-write-failed","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}