asgeirtj/system_prompts_leaks · error · Error
[SCHEDULER_MISSING] this DS's dist/ imports 'scheduler' dire
Error message
[SCHEDULER_MISSING] this DS's dist/ imports 'scheduler' directly — usually react-dom leaked into the dist. Check the DS build's externals.
What it means
The design-sync bundler registers an esbuild resolve plugin (bundle.mjs:65) that redirects any import matching /^scheduler(\/|$)/ to a 'scheduler-shim' module whose body is a bare throw (line 115). scheduler is React's internal scheduling dependency, pulled in transitively by react-dom; a properly externalized design-system dist/ never references it. If the dist/ does import scheduler, it means react-dom was inlined into the dist during the DS's own build rather than kept as an external/peer — shipping a second scheduler instance would break concurrent rendering (per the comment at line 63-64). The shim surfaces this as a loud, named error instead of a silent double-scheduler bug.
Source
Thrown at Anthropic/Claude Code/bundled-skills/design-sync/lib/bundle.mjs:115
function tt(o){return o!=null&&typeof o==="object"?(R.isValidElement(o)?(o.type&&o.type.$$typeof)||o.type:o.$$typeof):undefined}
exports.typeOf=tt;
exports.isElement=R.isValidElement;
exports.isValidElementType=function(t){return typeof t==="string"||typeof t==="function"||t===R.Fragment||t===R.Suspense||t===R.StrictMode||t===R.Profiler||(t!=null&&typeof t==="object"&&t.$$typeof!=null)};
exports.isFragment=function(o){return R.isValidElement(o)&&o.type===R.Fragment};
exports.isSuspense=function(o){return R.isValidElement(o)&&o.type===R.Suspense};
exports.isPortal=function(o){return o!=null&&o.$$typeof===PORTAL};
exports.isForwardRef=function(o){return tt(o)===FWD};
exports.isMemo=function(o){return tt(o)===MEMO};
exports.isLazy=function(o){return tt(o)===LAZY};
exports.isContextProvider=exports.isContextConsumer=exports.isProfiler=exports.isStrictMode=function(){return false};
exports.ForwardRef=FWD;exports.Memo=MEMO;exports.Portal=PORTAL;exports.Lazy=LAZY;
exports.Fragment=R.Fragment;exports.Suspense=R.Suspense;exports.StrictMode=R.StrictMode;exports.Profiler=R.Profiler;`,
loader: 'js',
}));
b.onLoad({ filter: /^scheduler-shim$/, namespace: 'shim' }, () => ({
// A DS dist/ rarely imports scheduler directly — when it does, it
// means react-dom leaked into the dist. Surface it.
contents: `throw new Error("[SCHEDULER_MISSING] this DS's dist/ imports 'scheduler' directly — usually react-dom leaked into the dist. Check the DS build's externals.");`,
loader: 'js',
}));
},
};
// Build a resolve plugin from tsconfig compilerOptions.paths. esbuild's
// built-in `tsconfig` option only applies paths to files covered by that
// tsconfig, which the synth entry (in OUT) isn't — so we resolve explicitly.
export function tsconfigPathsPlugin(tsconfigPath) {
let paths, baseUrl;
try {
// Strip // and /* */ comments — tsconfig.json permits them, JSON.parse doesn't.
const raw = readFileSync(tsconfigPath, 'utf8')
.replace(/\/\*[\s\S]*?\*\//g, '')
.replace(/(^|[^:])\/\/.*$/gm, '$1');
({ paths, baseUrl = '.' } = JSON.parse(raw).compilerOptions ?? {});
} catch { return null; }
if (!paths) return null;View on GitHub (pinned to 93c999115b)
Solutions
- Add 'react-dom' (and 'react', 'scheduler') to the DS build's `external` array in its rollup/webpack/esbuild config, then rebuild the dist.
- Ensure the DS package.json lists react-dom (and react) under `peerDependencies`, not `dependencies` — peer deps are never bundled.
- Verify the fix: grep the rebuilt dist output for `scheduler` — a correct externalized dist has zero hits.
- If the DS is third-party and you cannot rebuild it, contact the DS maintainer or pin to a DS version whose dist is correctly externalized.
Example fix
// before — DS build config (e.g. rollup.config.js) with no externals
export default {
input: 'src/index.ts',
output: { file: 'dist/index.js', format: 'esm' },
// react-dom gets bundled into dist/, pulling in scheduler
};
// after — mark react/react-dom/scheduler as external
export default {
input: 'src/index.ts',
output: { file: 'dist/index.js', format: 'esm' },
external: ['react', 'react-dom', 'scheduler'],
};
// package.json: "peerDependencies": { "react": ">=18", "react-dom": ">=18" } Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
// Scan the DS dist for a direct scheduler import BEFORE running
// the design-sync bundle step.
function assertNoSchedulerInDist(distDir) {
const re = /(?:from\s+['"]scheduler['"]|require\s*\(\s*['"]scheduler['"])/;
for (const f of readdirSync(distDir)) {
if (!f.endsWith('.js') && !f.endsWith('.mjs')) continue;
if (re.test(readFileSync(join(distDir, f), 'utf8'))) {
throw new Error(`${f} imports scheduler — rebuild DS with react-dom external`);
}
}
} Try / catch
// This is a build-time fail-fast: the throw lives in bundled output. // Catching it at runtime only masks the real problem (double scheduler). // Instead, fix the DS externals and rebuild — do NOT wrap in try/catch.
Prevention
- Keep react, react-dom, and scheduler in the DS build config's `external` array at all times — never remove them.
- List react and react-dom under `peerDependencies` (not `dependencies`) in the DS package.json so no bundler inlines them.
- Add a CI grep step that fails if the published dist/ contains the string 'scheduler' — a correct externalized dist never does.
- When migrating a DS into or out of a monorepo, diff the build config's externals explicitly — this is the most common way they get lost.
When it happens
Trigger: The DS was built without react-dom in its externals, so its bundler inlined react-dom (which imports scheduler) into the dist/. When design-sync's esbuild pipeline bundles that dist/ into a preview, the scheduler import hits the shim and the throw fires during module evaluation of the built preview.
Common situations: DS build config (rollup/webpack/esbuild/vite) missing 'react-dom' in the `external` array. DS package.json listing react-dom under `dependencies` instead of `peerDependencies`, so the bundler treats it as a regular dep to inline. Migrating a DS from a standalone repo into a monorepo and losing the externals config. A DS build that was accidentally run in full-bundle mode (no externals at all).
Related errors
AI-assisted analysis of asgeirtj/system_prompts_leaks@93c999115b (2026-08-13).
Data as JSON: /api/errors/dac17e8da0816719.
Report an issue: GitHub.