{"record":{"id":"c3a39088d632c07a","repo":"github/copilot-sdk","slug":"invalid-runtime-asset-inventory-entry","errorCode":null,"errorMessage":"Invalid runtime asset inventory entry: ","messagePattern":"Invalid runtime asset inventory entry: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java","lineNumber":456,"sourceCode":"\n    private static void extractRuntimeAssetsToCache(Path cacheDir, ClassLoader loader, String classifier,\n            AtomicPublisher publisher) throws IOException {\n        String inventoryResourcePath = \"native/\" + classifier + \"/\" + RUNTIME_ASSETS_FILENAME;\n        URL inventoryResource = loader.getResource(inventoryResourcePath);\n        if (inventoryResource == null) {\n            return;\n        }\n\n        try (BufferedReader reader = new BufferedReader(\n                new InputStreamReader(inventoryResource.openStream(), StandardCharsets.UTF_8))) {\n            String line;\n            while ((line = reader.readLine()) != null) {\n                if (line.isBlank()) {\n                    continue;\n                }\n                String[] fields = line.split(\"\\\\t\", 2);\n                if (fields.length != 2) {\n                    throw new IOException(\"Invalid runtime asset inventory entry: \" + line);\n                }\n                boolean executable = (Integer.parseInt(fields[0], 8) & 0111) != 0;\n                Path relative = Path.of(fields[1]).normalize();\n                if (relative.isAbsolute() || relative.startsWith(\"..\")) {\n                    throw new IOException(\"Unsafe runtime asset inventory path: \" + fields[1]);\n                }\n                Path cached = cacheDir.resolve(relative).normalize();\n                if (!cached.startsWith(cacheDir)) {\n                    throw new IOException(\"Runtime asset escapes cache directory: \" + fields[1]);\n                }\n                if (isValidCachedFile(cached) && (!executable || isWindows() || Files.isExecutable(cached))) {\n                    continue;\n                }\n\n                String resourcePath = \"native/\" + classifier + \"/\" + fields[1];\n                URL resource = loader.getResource(resourcePath);\n                if (resource == null) {\n                    throw new FileNotFoundException(\"Runtime asset not found on classpath: \" + resourcePath);","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java#L438-L474","documentation":"A line in the runtime-assets.list inventory resource did not split into exactly two tab-separated fields (octal mode and relative path). The loader treats the inventory as a strict manifest for extracting extra runtime assets, so a malformed line aborts extraction to avoid silently skipping assets.","triggerScenarios":"Calling resolve()/extractToCache() with a classifier JAR whose runtime-assets.list is corrupted, hand-edited, line-wrapped by a text editor, or uses spaces/newlines instead of tabs as separators.","commonSituations":"Locally regenerated classifier JARs where the manifest was written with spaces or CRLF-joined fields; a build step that re-formatted or minified resource files; truncated download of the classifier artifact.","solutions":["Replace the classifier JAR with an official release artifact whose runtime-assets.list is well-formed (mode<TAB>path per line).","Inspect the manifest: unzip -p copilot-sdk-native-*.jar native/<classifier>/runtime-assets.list and check each line has exactly one tab.","If building the JAR yourself, fix the manifest generation step to emit tab-separated mode and path fields.","Purge the cached/local Maven copy and re-download to rule out artifact corruption."],"exampleFix":"// before: runtime-assets.list (malformed)\n0755 assets/node_modules/module.js\n 0755  extra/tool\n\n// after (mode<TAB>relative path, one per line)\n0755\tassets/node_modules/module.js\n0755\textra/tool","handlingStrategy":"validation","validationCode":"try (BufferedReader r = new BufferedReader(new InputStreamReader(\n        getClass().getResourceAsStream(\"/native/\" + classifier + \"/runtime-assets.list\"), UTF_8))) {\n    String line;\n    while ((line = r.readLine()) != null)\n        if (!line.isBlank() && line.split(\"\\t\", -1).length < 2)\n            throw new IllegalStateException(\"Malformed runtime-assets.list entry: \" + line);\n}\n","typeGuard":null,"tryCatchPattern":"try {\n    Path runtime = NativeRuntimeLoader.resolve();\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Invalid runtime asset inventory entry\")) {\n        throw new IllegalStateException(\"Classifier JAR manifest is corrupt; replace with an official artifact\", e);\n    } else throw e;\n}","preventionTips":["Use official classifier JAR artifacts; don't regenerate resources manually.","Keep runtime-assets.list strictly tab-separated with one entry per line (LF endings).","Validate the manifest as part of the native packaging CI.","Re-download artifacts if a build suddenly starts failing with inventory errors."],"tags":["native-loader","manifest","classpath","corrupt-artifact"],"backgroundTag":"invalid-argument-format","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}