{"record":{"id":"7765c5190bc0c8ef","repo":"conductor-oss/conductor","slug":"skill-file-is-too-large-to-preview-cleanpath","errorCode":null,"errorMessage":"Skill file is too large to preview: {cleanPath}","messagePattern":"Skill file is too large to preview: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java","lineNumber":279,"sourceCode":"        requireSkillStorage();\n        if (path == null || path.isBlank()) {\n            throw new IllegalArgumentException(\"File path is required\");\n        }\n        String cleanPath = normalizeEntryName(path);\n        SkillDetail detail = get(name, version);\n        byte[] packageBytes = packageBytes(detail);\n        try (ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(packageBytes))) {\n            ZipEntry entry;\n            while ((entry = zip.getNextEntry()) != null) {\n                if (entry.isDirectory()) {\n                    continue;\n                }\n                String entryName = normalizeEntryName(entry.getName());\n                if (!entryName.equals(cleanPath)) {\n                    continue;\n                }\n                if (entry.getSize() > maxPreviewBytes) {\n                    throw new IllegalArgumentException(\n                            \"Skill file is too large to preview: \" + cleanPath);\n                }\n                byte[] data =\n                        readBounded(\n                                zip,\n                                maxPreviewBytes,\n                                \"Skill file is too large to preview: \" + cleanPath);\n                boolean binary = isBinary(cleanPath, data);\n                return SkillFileContent.builder()\n                        .path(cleanPath)\n                        .contentType(contentType(cleanPath))\n                        .size(data.length)\n                        .binary(binary)\n                        .content(binary ? null : new String(data, StandardCharsets.UTF_8))\n                        .contentBase64(binary ? Base64.getEncoder().encodeToString(data) : null)\n                        .build();\n            }\n            throw new IllegalArgumentException(\"Skill file not found: \" + cleanPath);","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java#L261-L297","documentation":"Thrown by readFile() when the matched zip entry's reported size (entry.getSize()) exceeds maxPreviewBytes (default 1,048,576 = 1 MiB, configurable via agentspan.skills.max-preview-bytes). This is the fast pre-read size check that avoids loading a large file into memory. It uses the zip central-directory size, so it triggers before any byte is streamed.","triggerScenarios":"GET /api/skills/{name}/versions/{version}/files?path=assets/big-image.png where the entry size is > 1 MiB. Fires when previewing a large bundled asset, data file, or oversized doc.","commonSituations":"Skills that bundle large reference datasets or images; lowering max-preview-bytes in config then previewing previously-readable files; a skill author committing a multi-MB asset into the package root.","solutions":["Download the full package instead of previewing: GET /api/skills/{name}/versions/{version}/package.","Raise agentspan.skills.max-preview-bytes in application config if previewing large files is intended.","Move large files out of the skill package, or split them so the previewed entry is under the limit."],"exampleFix":"# before (preview blocked on >1MiB entry)\nGET /api/skills/foo/versions/1.0.0/files?path=assets/large.bin\n# after (download full package instead)\nGET /api/skills/foo/versions/1.0.0/package","handlingStrategy":"validation","validationCode":"// Client-side: check the entry size from the skill detail before previewing\nSkillDetail d = skillRegistryService.get(name, version);\nSkillFileEntry entry = d.getFiles().stream()\n    .filter(f -> f.getPath().equals(path)).findFirst().orElseThrow();\nif (entry.getSize() > maxPreviewBytes) { /* use package download instead */ }","typeGuard":"static boolean isPreviewable(SkillFileEntry e, long maxPreviewBytes) {\n    return e.getSize() >= 0 && e.getSize() <= maxPreviewBytes;\n}","tryCatchPattern":"try { return skillRegistryService.readFile(name, version, path); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"too large to preview\")) { return downloadPackageInstead(name, version); }\n    throw e;\n}","preventionTips":["Surface the max-preview-bytes limit to the UI so it can choose preview vs. download up front.","Avoid bundling files larger than the preview cap inside skill packages."],"tags":["java","conductor","skill-registry","size-limit","preview"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}