laurent22/joplin · error · Error
${screenshotType} is not a valid screenshot type. Valid type
Error message
${screenshotType} is not a valid screenshot type. Valid types are:
${allPossibleScreenshotsType}
What it means
Thrown by validateScreenshots() after extracting the file extension via `screenshot.src.split('.').pop()`. The extension must be in allPossibleScreenshotsType. Only local files reach this check — https:// and http:// src values `continue` early and bypass it.
Source
Thrown at packages/generator-joplin/generators/app/templates/webpack.config.js:111
if ((categories.length !== new Set(categories).size)) throw new Error('Repeated categories are not allowed');
// eslint-disable-next-line github/array-foreach -- Old code before rule was applied
categories.forEach(category => {
if (!allPossibleCategories.map(category => { return category.name; }).includes(category)) throw new Error(`${category} is not a valid category. Please make sure that the category name is lowercase. Valid categories are: \n${allPossibleCategories.map(category => { return category.name; })}\n`);
});
}
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;
}View on GitHub (pinned to 2654b33620)
Solutions
- Convert the screenshot to a supported type — the valid list is printed in the error message.
- Rename the file so its extension is lowercase and matches an entry in allPossibleScreenshotsType.
- If the file genuinely has no extension, add the correct one.
- Re-run the build.
Example fix
// before "src": "screenshots/hero.BMP" // after (convert + rename) "src": "screenshots/hero.png"
Defensive patterns
Strategy: validation
Validate before calling
const supported = new Set(allPossibleScreenshotsType); // exported list
const bad = (manifest.screenshots || [])
.filter(s => s.src && !/^https?:\/\//.test(s.src))
.filter(s => !supported.has(s.src.split('.').pop().toLowerCase()));
if (bad.length) throw new Error(`Unsupported screenshot type for: ${bad.map(s => s.src).join(', ')}`); Type guard
const isSupportedScreenshotType = (src, supported) => /^https?:\/\//.test(src) || supported.has(src.split('.').pop().toLowerCase()); Try / catch
try { validateScreenshots(manifest.screenshots); }
catch (e) { if (/not a valid screenshot type/.test(e.message)) { /* convert or replace */ } else throw e; } Prevention
- Normalise screenshot filenames to a single supported extension when adding them to the repo.
- Lowercase extensions on commit via a pre-commit hook to avoid case mismatch with the supported list.
When it happens
Trigger: A local screenshot src has an extension that is not in allPossibleScreenshotsType (e.g. .bmp, .tiff, .webp if unsupported), or src has no dot so split('.').pop() returns the whole filename.
Common situations: Author exports a screenshot in an uncommon format; file has no extension; case mismatch where the list expects lowercase but the file uses uppercase (.PNG).
Related errors
- ${category} is not a valid category. Please make sure that t
- You must specify a src for each screenshot
- Max screenshot file size is ${fileMaxSize}KB. ${screenshotPa
- Manifest plugin ID is not set in ${manifestPath}
- Plugin archive was not created because the "dist" directory
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/51544c0f3909136d.
Report an issue: GitHub.