{"record":{"id":"8ad8fb69844a5695","repo":"laurent22/joplin","slug":"max-screenshot-file-size-is-filemaxsize-kb-sc","errorCode":null,"errorMessage":"Max screenshot file size is ${fileMaxSize}KB. ${screenshotPath} is ${fileSize}KB","messagePattern":"Max screenshot file size is (.+?)KB\\. (.+?) is (.+?)KB","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/generator-joplin/generators/app/templates/webpack.config.js","lineNumber":118,"sourceCode":"function validateScreenshots(screenshots) {\n\tif (!screenshots) return null;\n\tfor (const screenshot of screenshots) {\n\t\tif (!screenshot.src) throw new Error('You must specify a src for each screenshot');\n\n\t\t// Avoid attempting to download and verify URL screenshots.\n\t\tif (screenshot.src.startsWith('https://') || screenshot.src.startsWith('http://')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst screenshotType = screenshot.src.split('.').pop();\n\t\tif (!allPossibleScreenshotsType.includes(screenshotType)) throw new Error(`${screenshotType} is not a valid screenshot type. Valid types are: \\n${allPossibleScreenshotsType}\\n`);\n\n\t\tconst screenshotPath = path.resolve(rootDir, screenshot.src);\n\n\t\t// Max file size is 1MB\n\t\tconst fileMaxSize = 1024;\n\t\tconst fileSize = fs.statSync(screenshotPath).size / 1024;\n\t\tif (fileSize > fileMaxSize) throw new Error(`Max screenshot file size is ${fileMaxSize}KB. ${screenshotPath} is ${fileSize}KB`);\n\t}\n}\n\nfunction readManifest(manifestPath) {\n\tconst content = fs.readFileSync(manifestPath, 'utf8');\n\tconst output = JSON.parse(content);\n\tif (!output.id) throw new Error(`Manifest plugin ID is not set in ${manifestPath}`);\n\tvalidateCategories(output.categories);\n\tvalidateScreenshots(output.screenshots);\n\treturn output;\n}\n\nfunction createPluginArchive(sourceDir, destPath) {\n\tconst distFiles = glob.sync(`${sourceDir}/**/*`, { nodir: true, windowsPathsNoEscape: true })\n\t\t.map(f => f.substr(sourceDir.length + 1));\n\n\tif (!distFiles.length) throw new Error('Plugin archive was not created because the \"dist\" directory is empty');\n\tfs.removeSync(destPath);","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/generator-joplin/generators/app/templates/webpack.config.js#L100-L136","documentation":"Thrown by validateScreenshots() after fs.statSync measures the local screenshot file. fileMaxSize is hardcoded to 1024 (KB), i.e. 1 MiB. Files larger than that abort the build. URL-based screenshots skip this check because of the early `continue`.","triggerScenarios":"screenshot.src is a local path, fs.statSync reports size/1024 > 1024 — i.e. the file exceeds 1 MiB.","commonSituations":"Author commits a high-resolution PNG straight from a screenshot tool without compressing; lossless screenshots of full-screen content easily exceed 1 MiB.","solutions":["Compress or resize the screenshot to under 1 MiB (e.g. pngquant, tinypng, or export as JPEG at ~80% quality).","Crop to the relevant region to cut bytes.","If compression is not viable, host the image at a URL and set src to https://... so the size check is skipped.","Re-run the build and confirm the new file size is below 1024 KB."],"exampleFix":"# before\n\"src\": \"screenshots/hero.png\"  # 2.4 MB file\n# after (compress)\npngquant --quality=70-85 screenshots/hero.png\n# or move to URL\n\"src\": \"https://example.com/hero.png\"","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nconst MAX_KB = 1024;\nfor (const s of manifest.screenshots || []) {\n  if (s.src && !/^https?:\\/\\//.test(s.src)) {\n    const sizeKb = fs.statSync(s.src).size / 1024;\n    if (sizeKb > MAX_KB) throw new Error(`Oversize screenshot ${s.src}: ${sizeKb} KB`);\n  }\n}","typeGuard":"const isWithinSize = (sizeBytes, maxKb) => typeof sizeBytes === 'number' && sizeBytes / 1024 <= maxKb;","tryCatchPattern":"try { validateScreenshots(manifest.screenshots); }\ncatch (e) { if (/Max screenshot file size/.test(e.message)) { /* compress or move to URL */ } else throw e; }","preventionTips":["Run screenshots through pngquant/tinypng before commit.","Add a CI step that fails if any screenshot under ./screenshots exceeds 1 MiB."],"tags":["plugin-build","manifest-validation","file-size","generator-joplin"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}