laurent22/joplin · error · Error

Max screenshot file size is ${fileMaxSize}KB. ${screenshotPa

Error message

Max screenshot file size is ${fileMaxSize}KB. ${screenshotPath} is ${fileSize}KB

What it means

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`.

Source

Thrown at packages/generator-joplin/generators/app/templates/webpack.config.js:118

function validateScreenshots(screenshots) {
	if (!screenshots) return null;
	for (const screenshot of screenshots) {
		if (!screenshot.src) throw new Error('You must specify a src for each screenshot');

		// Avoid attempting to download and verify URL screenshots.
		if (screenshot.src.startsWith('https://') || screenshot.src.startsWith('http://')) {
			continue;
		}

		const screenshotType = screenshot.src.split('.').pop();
		if (!allPossibleScreenshotsType.includes(screenshotType)) throw new Error(`${screenshotType} is not a valid screenshot type. Valid types are: \n${allPossibleScreenshotsType}\n`);

		const screenshotPath = path.resolve(rootDir, screenshot.src);

		// Max file size is 1MB
		const fileMaxSize = 1024;
		const fileSize = fs.statSync(screenshotPath).size / 1024;
		if (fileSize > fileMaxSize) throw new Error(`Max screenshot file size is ${fileMaxSize}KB. ${screenshotPath} is ${fileSize}KB`);
	}
}

function readManifest(manifestPath) {
	const content = fs.readFileSync(manifestPath, 'utf8');
	const output = JSON.parse(content);
	if (!output.id) throw new Error(`Manifest plugin ID is not set in ${manifestPath}`);
	validateCategories(output.categories);
	validateScreenshots(output.screenshots);
	return output;
}

function createPluginArchive(sourceDir, destPath) {
	const distFiles = glob.sync(`${sourceDir}/**/*`, { nodir: true, windowsPathsNoEscape: true })
		.map(f => f.substr(sourceDir.length + 1));

	if (!distFiles.length) throw new Error('Plugin archive was not created because the "dist" directory is empty');
	fs.removeSync(destPath);

View on GitHub (pinned to 2654b33620)

Solutions

  1. Compress or resize the screenshot to under 1 MiB (e.g. pngquant, tinypng, or export as JPEG at ~80% quality).
  2. Crop to the relevant region to cut bytes.
  3. If compression is not viable, host the image at a URL and set src to https://... so the size check is skipped.
  4. Re-run the build and confirm the new file size is below 1024 KB.

Example fix

# before
"src": "screenshots/hero.png"  # 2.4 MB file
# after (compress)
pngquant --quality=70-85 screenshots/hero.png
# or move to URL
"src": "https://example.com/hero.png"
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const MAX_KB = 1024;
for (const s of manifest.screenshots || []) {
  if (s.src && !/^https?:\/\//.test(s.src)) {
    const sizeKb = fs.statSync(s.src).size / 1024;
    if (sizeKb > MAX_KB) throw new Error(`Oversize screenshot ${s.src}: ${sizeKb} KB`);
  }
}

Type guard

const isWithinSize = (sizeBytes, maxKb) => typeof sizeBytes === 'number' && sizeBytes / 1024 <= maxKb;

Try / catch

try { validateScreenshots(manifest.screenshots); }
catch (e) { if (/Max screenshot file size/.test(e.message)) { /* compress or move to URL */ } else throw e; }

Prevention

When it happens

Trigger: screenshot.src is a local path, fs.statSync reports size/1024 > 1024 — i.e. the file exceeds 1 MiB.

Common situations: Author commits a high-resolution PNG straight from a screenshot tool without compressing; lossless screenshots of full-screen content easily exceed 1 MiB.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/8ad8fb69844a5695. Report an issue: GitHub.