koala73/worldmonitor · error · Error
no initial JS assets referenced by ${dashboardPath} — run: $
Error message
no initial JS assets referenced by ${dashboardPath} — run: ${BUILD_COMMANDS.dashboard} What it means
initialDashboardAssetNames scans dashboard.html for src/href references to .js assets under assets/ to compute initial bundle budgets. If the regex collects zero asset names, it throws, assuming the HTML is not a real Vite production build (which always references at least one JS asset). This prevents measuring an empty/stub HTML and reporting bogus zero-byte budgets.
Solutions
- Run BUILD_COMMANDS.dashboard to produce a real production build in distDir and retry
- Inspect dist/dashboard.html — confirm it references hashed assets under assets/
- If assets live under a different path, fix assetFileNameFromUrl in scripts/bundle-budgets.mjs or the Vite base/assetsDir config so URLs resolve to asset file names
- Point the script at the correct distDir if it was aimed at the source template or dev output
Example fix
// before: dev HTML referenced by budgets vite build --mode development // emits /src/main.ts references // after vite build // emits <script type="module" src="/assets/index-abc123.js">
Defensive patterns
Strategy: validation
Validate before calling
const html = readFileSync(join(distDir, 'dashboard.html'), 'utf8');
if (!/(?:src|href)=["'][^"']+.js(?:[?#][^"']*)?["']/i.test(html)) throw new Error('dashboard.html references no JS assets — run the production build'); Type guard
const referencesJsAssets = (html) => /(?:src|href)=["'][^"']+\.js(?:[?#][^"']*)?["']/i.test(html);
Try / catch
try {
const assets = initialDashboardAssetNames(distDir);
} catch (e) {
if (e.message.includes('no initial JS assets')) {
console.error('Rebuild with the production Vite build before measuring budgets');
process.exitCode = 1;
} else throw e;
} Prevention
- Run the production (not dev/development-mode) build before budget checks
- Keep asset references under assets/ so hashed URLs are extractable
- Don't hand-edit dashboard.html; treat it as build output
- CI: generate the build in the same job that runs budget checks
When it happens
Trigger: Calling initialDashboardAssetNames against a dashboard.html that contains no `<script src>`/`<link href>` pointing at assets/*.js — e.g. a dev-mode HTML (scripts served from /src as type=module without hashed asset URLs), a manually authored placeholder HTML, or a Vite config change that stops emitting hashed asset references.
Common situations: Budget script accidentally pointed at the dev server HTML or a source template instead of dist; Vite `build` produced only CSS (no JS chunks due to config error); build.config change renamed the assets subdirectory so assetFileNameFromUrl returns null for every match.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- no module entry script in ${dashboardPath} — run: ${BUILD_CO
- ${PRO_HTML_PATH} must carry exactly one dateModified node (f
- cannot read ${dashboardPath} — run: ${BUILD_COMMANDS.dashboa
- cannot read dashboard entry ${entryPath}: ${error.message}
- Valid phone number is required
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/ac3802469466eb0d.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/bundle-budgets.mjs:179
function readDashboardHtml(distDir) {
const dashboardPath = join(distDir, 'dashboard.html');
try {
return { dashboardPath, html: readFileSync(dashboardPath, 'utf8') };
} catch (error) {
throw new Error(`cannot read ${dashboardPath} — run: ${BUILD_COMMANDS.dashboard}: ${error.message}`);
}
}
export function initialDashboardAssetNames(distDir) {
const { dashboardPath, html } = readDashboardHtml(distDir);
const assets = new Set();
for (const match of html.matchAll(/(?:src|href)=["']([^"']+\.js(?:[?#][^"']*)?)["']/gi)) {
const fileName = assetFileNameFromUrl(match[1]);
if (fileName) assets.add(fileName);
}
if (assets.size === 0) {
throw new Error(`no initial JS assets referenced by ${dashboardPath} — run: ${BUILD_COMMANDS.dashboard}`);
}
return [...assets].sort();
}
/**
* The asset files Vite preloads for the dashboard entry's deferred
* `import('./App-<hash>.js')`, in preload-list order and including CSS, or
* null when the entry has no such import (App is then in the initial payload).
*
* Vite emits the loader as `P(() => import('./App-x.js')…, __vite__mapDeps([…]))`,
* where the indices point into one `m.f=[…]` table and the list starts with
* the imported chunk itself. Anything that breaks that shape throws: a parser
* that silently measured the wrong list would let the application graph grow
* unseen.
*/
export function deferredDashboardAppDependencies(distDir) {
const { dashboardPath, html } = readDashboardHtml(distDir);
const entryUrl = /<script\b[^>]*\btype=["']module["'][^>]*\bsrc=["']([^"']+\.js(?:[?#][^"']*)?)["']/iView on GitHub (pinned to 7d06c8633d)