apple/pkl · error · DocGeneratorBugException

I/O error reading `${path.toUri()}`.

Error message

I/O error reading `${path.toUri()}`.

What it means

PackageDataGenerator.read loads serialized PackageData from a JSON file on disk and wraps any IOException from reading that file into a DocGeneratorBugException with this message. It indicates the package data file could not be read (missing, unreadable, or an I/O failure), with the original IOException attached as cause.

Source

Thrown at pkl-doc/src/main/kotlin/org/pkl/doc/PackageDataGenerator.kt:249

  /** The source code pattern, with placeholders (e.g. `%{path}`) */
  val sourceCodeUrlScheme: String?,

  /** The dependencies of this package. */
  val dependencies: List<DependencyData> = listOf(),

  /** The modules in this package. */
  val modules: List<ModuleData> = listOf(),
) {
  companion object {
    val json = Json { serializersModule = serializers }

    fun read(path: Path): PackageData {
      val jsonStr: String =
        try {
          path.readString()
        } catch (e: IOException) {
          throw DocGeneratorBugException("I/O error reading `${path.toUri()}`.", e)
        }

      return try {
        json.decodeFromString(jsonStr)
      } catch (e: SerializationException) {
        throw DocGeneratorBugException("Error deserializing `${path.toUri()}`.", e)
      }
    }
  }

  constructor(
    pkg: DocPackage
  ) : this(
    PackageRef(pkg.name, pkg.uri, pkg.version),
    getDocCommentSummary(pkg.overview),
    pkg.docPackageInfo.annotations.deprecation,
    pkg.docPackageInfo.sourceCode,
    pkg.docPackageInfo.sourceCodeUrlScheme,

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Check the wrapped IOException cause for the exact path and reason
  2. Verify the package data file exists at the given path and is readable
  3. Regenerate or restore the missing package data file before reading

Example fix

// before
val data = PackageDataGenerator.read(dataPath) // throws if file missing
// after
if (dataPath.exists()) {
  val data = PackageDataGenerator.read(dataPath)
} else {
  regeneratePackageData(dataPath)
}
Defensive patterns

Strategy: try-catch

Validate before calling

require(dataPath.isRegularFile() && dataPath.isReadable()) { "Package data file missing or unreadable: $dataPath" }

Try / catch

try { val data = PackageDataGenerator.read(path) } catch (e: DocGeneratorBugException) { val io = e.cause as? IOException ?: throw e; logger.error("read failed", io) }

Prevention

When it happens

Trigger: Calling PackageDataGenerator.read(path) where path.readString() throws IOException — file does not exist, no read permission, path is a directory, or a transient I/O error occurs.

Common situations: Running migration/regeneration on an incomplete output directory; files deleted by a clean task mid-run; wrong outputDir configured so the expected data file path doesn't exist.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/9d3df628745cc723. Report an issue: GitHub.