{"record":{"id":"deeff0138f56e26a","repo":"apple/pkl","slug":"error-deserializing-path-touri-deeff0","errorCode":null,"errorMessage":"Error deserializing `${path.toUri()}`.","messagePattern":"Error deserializing `(.+?)`\\.","errorType":"exception","errorClass":"DocGeneratorBugException","httpStatus":null,"severity":"error","filePath":"pkl-doc/src/main/kotlin/org/pkl/doc/RuntimeData.kt","lineNumber":76,"sourceCode":"            if (comparison != 0) return@Comparator comparison\n          } catch (_: Throwable) {\n            // possibly happens if the version is invalid.\n            continue\n          }\n        }\n        0\n      }\n    }\n\n    fun readOrEmpty(path: Path): RuntimeData {\n      return try {\n        json.decodeFromString(path.readString())\n      } catch (e: Throwable) {\n        when (e) {\n          is NoSuchFileException,\n          is FileNotFoundException -> EMPTY\n          is SerializationException ->\n            throw DocGeneratorBugException(\"Error deserializing `${path.toUri()}`.\", e)\n          else -> throw e\n        }\n      }\n    }\n  }\n\n  fun <T : ElementRef<*>> addKnownVersions(\n    myRef: T,\n    versions: Set<String>?,\n    comparator: Comparator<String>,\n  ): RuntimeData {\n    if (versions == null) return this\n    val newEffectiveVersions = knownVersions.mapTo(mutableSetOf()) { it.text } + versions\n    val knownVersions =\n      newEffectiveVersions\n        .sortedWith(comparator)\n        .map { version -> RuntimeDataLink(text = version, href = myRef.pageUrlForVersion(version)) }\n        .toSet()","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-doc/src/main/kotlin/org/pkl/doc/RuntimeData.kt#L58-L94","documentation":"RuntimeData.readOrEmpty reads cached runtime data from a JSON file and deserializes it. A missing file is treated as empty, but a kotlinx SerializationException (the file exists yet cannot be parsed into the expected schema) is wrapped in a DocGeneratorBugException with the file URI in the message.","triggerScenarios":"Calling readOrEmpty when the file at `path` exists but contains JSON that fails to deserialize into the expected @Serializable type (corrupt cache, schema mismatch between generator versions).","commonSituations":"Stale or hand-edited cache files, a pkl-doc version upgrade changing the cached data schema, truncated file from a previous crashed run.","solutions":["Delete the cached data file so it is regenerated from scratch.","Ensure the cache was written by the same pkl-doc version now reading it.","Validate the JSON structure against the expected RuntimeData schema.","Check the wrapped SerializationException message for the exact field/type mismatch."],"exampleFix":"// before\nval data = RuntimeData.readOrEmpty(staleCachePath) // SerializationException\n// after\nstaleCachePath.deleteIfExists() // regenerate cache on version upgrade\nval data = RuntimeData.readOrEmpty(staleCachePath)","handlingStrategy":"validation","validationCode":"val f = File(cachePath)\nif (f.exists()) runCatching { Json.decodeFromString<RuntimeData>(f.readText()) }.onFailure { f.delete() }","typeGuard":null,"tryCatchPattern":"try { RuntimeData.readOrEmpty(path) } catch (e: DocGeneratorBugException) { Files.deleteIfExists(path); RuntimeData.readOrEmpty(path) }","preventionTips":["Bump/clear cache dirs when upgrading pkl-doc versions","Never hand-edit generated cache JSON","Guard against truncated writes from crashed runs","Validate cache JSON in CI before consuming"],"tags":["json","deserialization","kotlin","cache"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}