{"record":{"id":"23d2fd23d4a4ccae","repo":"apple/pkl","slug":"failed-to-load-class-path-resource-resourcename","errorCode":null,"errorMessage":"Failed to load class path resource `$resourceName`.","messagePattern":"Failed to load class path resource `\\$resourceName`\\.","errorType":"exception","errorClass":"DocGeneratorException","httpStatus":null,"severity":"error","filePath":"pkl-doc/src/main/kotlin/org/pkl/doc/Util.kt","lineNumber":40,"sourceCode":"import java.nio.file.Path\nimport java.nio.file.StandardCopyOption\nimport kotlin.io.path.createParentDirectories\nimport org.pkl.core.*\nimport org.pkl.core.util.IoUtils\nimport org.pkl.parser.Lexer\n\n// overwrites any existing file\ninternal fun copyResource(resourceName: String, targetDir: Path) {\n  val targetFile = targetDir.resolve(resourceName).apply { createParentDirectories() }\n  Files.copy(getResourceAsStream(resourceName), targetFile, StandardCopyOption.REPLACE_EXISTING)\n}\n\ninternal fun getResourceAsStreamOrNull(resourceName: String): InputStream? =\n  Thread.currentThread().contextClassLoader.getResourceAsStream(\"org/pkl/doc/$resourceName\")\n\ninternal fun getResourceAsStream(resourceName: String): InputStream =\n  getResourceAsStreamOrNull(resourceName)\n    ?: throw DocGeneratorException(\"Failed to load class path resource `$resourceName`.\")\n\ninternal val ModuleSchema?.hasListedClass: Boolean\n  get() = this != null && allClasses.any { !it.value.isUnlisted }\n\ninternal val ModuleSchema?.hasListedTypeAlias: Boolean\n  get() = this != null && allTypeAliases.any { !it.value.isUnlisted }\n\ninternal val PClass?.hasListedProperty: Boolean\n  get() = this != null && allProperties.any { !it.value.isUnlisted }\n\ninternal val PClass?.hasListedMethod: Boolean\n  get() = this != null && allMethods.any { !it.value.isUnlisted }\n\ninternal val Member.isUnlisted: Boolean\n  get() = annotations.isUnlisted\n\ninternal val List<PObject>.isUnlisted: Boolean\n  get() = any { it.classInfo == PClassInfo.Unlisted }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-doc/src/main/kotlin/org/pkl/doc/Util.kt#L22-L58","documentation":"getResourceAsStream loads a template/resource from the classpath under org/pkl/doc/. If the classloader cannot find the named resource, it throws a DocGeneratorException naming the missing resource. This indicates the pkl-doc library's bundled resources are absent from the runtime classpath.","triggerScenarios":"copyResource being asked for a resource name that is not on the classpath, e.g. a packaged jar missing its resources, a custom classloader (Shade/Gradle shadow) stripping resources, or a typo'd resource name.","commonSituations":"Shadow/fat-jar builds excluding non-class resources, GraalVM native-image without resource inclusion config, running pkl-doc from an incompletely assembled distribution.","solutions":["Rebuild/reinstall pkl-doc so its bundled resources under org/pkl/doc/ are on the classpath.","If using shadow/proguard/minimization, exclude org/pkl/doc/** resources from stripping.","For GraalVM native-image, register org/pkl/doc/** resources in resource-config.","Verify the resource name passed to copyResource matches an existing bundled file."],"exampleFix":"// before (shadowJar strips resources)\nshadowJar {\n  minimize()\n}\n// after\nshadowJar {\n  minimize { exclude(dependency(\"org.pkl-lang:.*:.*\")) }\n}","handlingStrategy":"try-catch","validationCode":"check(Thread.currentThread().contextClassLoader.getResource(\"org/pkl/doc/\") != null) { \"pkl-doc resources missing from classpath\" }","typeGuard":"fun hasDocResource(name: String) = getResourceAsStreamOrNull(name) != null","tryCatchPattern":"try { copyResource(name) } catch (e: DocGeneratorException) { logger.error(\"Missing bundled resource: ${e.message}; reinstall pkl-doc\") }","preventionTips":["Disable minimization/proguard stripping of org/pkl/doc/** resources","Register resources in GraalVM native-image config","Smoke-test resource loading after packaging changes","Use getResourceAsStreamOrNull for soft checks"],"tags":["classpath","resource-not-found","kotlin","build"],"backgroundTag":"resource-not-found","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"}