laurent22/joplin · error · Error
Plugin archive was not created because the "dist" directory
Error message
Plugin archive was not created because the "dist" directory is empty
What it means
Thrown by createPluginArchive() when glob.sync over `${sourceDir}/**/*` returns zero files. The dist directory is expected to contain the built plugin output before archiving into the .jpl tar. An empty dist means there is nothing to ship.
Source
Thrown at packages/generator-joplin/generators/app/templates/webpack.config.js:135
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);
tar.create(
{
strict: true,
portable: true,
file: destPath,
cwd: sourceDir,
sync: true,
},
distFiles,
);
console.info(chalk.cyan(`Plugin archive has been created in ${destPath}`));
}
const writeManifest = (manifestPath, content) => {
fs.writeFileSync(manifestPath, JSON.stringify(content, null, '\t'), 'utf8');View on GitHub (pinned to 2654b33620)
Solutions
- Run the build step first (e.g. `npm run build` / `yarn build`) so dist/ is populated before archiving.
- Verify dist/ actually contains the emitted index.js and assets (ls dist).
- Check webpack output.path matches the sourceDir passed to createPluginArchive.
- If the build step failed, fix the upstream error before re-running dist.
Example fix
# before npm run dist # dist/ is empty # after npm run build && npm run dist
Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
const path = require('path');
const hasFiles = (dir) => fs.existsSync(dir) && fs.readdirSync(dir).some(f => fs.statSync(path.join(dir, f)).isFile());
if (!hasFiles(distDir)) throw new Error('dist/ is empty — run the build step first'); Type guard
const distHasOutput = (dir) => fs.existsSync(dir) && fs.readdirSync(dir).length > 0;
Try / catch
try { createPluginArchive(distDir, destPath); }
catch (e) { if (/"dist" directory is empty/.test(e.message)) { /* run build, then retry */ } else throw e; } Prevention
- Sequence npm scripts so `build` always runs before `dist`.
- Fail the dist script early with a clearer message if dist/ is empty, before reaching createPluginArchive.
When it happens
Trigger: createPluginArchive(distDir, destPath) is called but distDir contains no files — glob with nodir:true returns an empty array.
Common situations: Build script ran `npm run dist` before `npm run build`; webpack build failed silently or wrote to a different output dir; dist was cleaned and never rebuilt; misconfigured output.path in webpack.
Related errors
- ${category} is not a valid category. Please make sure that t
- You must specify a src for each screenshot
- ${screenshotType} is not a valid screenshot type. Valid type
- Max screenshot file size is ${fileMaxSize}KB. ${screenshotPa
- Manifest plugin ID is not set in ${manifestPath}
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/47275ec81b4225f9.
Report an issue: GitHub.