{"record":{"id":"95e0c78db615a7b9","repo":"halo-dev/halo","slug":"esm-ui-provider-output-must-contain-at-most-one-en-95e0c7","errorCode":null,"errorMessage":"ESM UI provider output must contain at most one entry stylesheet.","messagePattern":"ESM UI provider output must contain at most one entry stylesheet\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ui/packages/ui-plugin-bundler-kit/src/vite-esm.ts","lineNumber":55,"sourceCode":"        const chunks = Object.values(bundle).filter(\n          (item) => item.type === \"chunk\"\n        );\n        for (const chunk of chunks) {\n          await validator.validateSource(chunk.code, chunk.fileName);\n        }\n\n        const entries = chunks.filter((chunk) => chunk.isEntry);\n        if (entries.length !== 1 || !entries[0].exports.includes(\"default\")) {\n          throw new Error(\n            \"ESM UI provider output must contain one entry with a default PluginModule export.\"\n          );\n        }\n        const entryStyles = [\n          ...((entries[0] as ViteOutputChunkMetadata).viteMetadata\n            ?.importedCss || []),\n        ].sort();\n        if (entryStyles.length > 1) {\n          throw new Error(\n            \"ESM UI provider output must contain at most one entry stylesheet.\"\n          );\n        }\n        const manifest = validateEsmProviderManifest({\n          format: \"esm\",\n          entry: `./${entries[0].fileName}`,\n          ...(entryStyles[0] ? { style: `./${entryStyles[0]}` } : {}),\n        });\n        this.emitFile({\n          type: \"asset\",\n          fileName: ESM_PROVIDER_MANIFEST,\n          source: `${JSON.stringify(manifest, null, 2)}\\n`,\n        });\n\n        const report = validator.getBuildReport();\n        resolvedConfig.logger.info(report.summary);\n        if (report.warning) {\n          resolvedConfig.logger.warn(report.warning);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/ui/packages/ui-plugin-bundler-kit/src/vite-esm.ts#L37-L73","documentation":"Thrown in generateBundle when the single ESM entry chunk imports more than one CSS stylesheet (viteMetadata.importedCss has 2+ entries). The ESM provider manifest supports at most one entry style (the 'style' field), so multiple stylesheets cannot be represented; emitting a manifest that silently drops styles would break the plugin's UI.","triggerScenarios":"The entry module statically imports two or more distinct .css files (e.g. `import './a.css'` and `import './b.css'`), or imports a CSS file plus a component library that ships its own CSS as a separate chunk import.","commonSituations":"Importing Tailwind directives plus a third-party component CSS; an entry that imports two style files for theming; a CSS split caused by async chunking that Vite attributes to the entry's importedCss set.","solutions":["Consolidate all entry CSS into a single file (e.g. one main.css that @imports or @layers the others) and import only that from the entry.","Remove the second static CSS import from the entry; load peripheral styles lazily if needed.","If a dependency injects CSS, configure Vite to inline/merge CSS for the ESM build (build.cssCodeSplit: false) so only one stylesheet reaches the entry."],"exampleFix":"// before (entry.ts)\nimport \"./styles/base.css\";\nimport \"./styles/theme.css\";\n\n// after\nimport \"./styles/index.css\"; // index.css contains both via @import","handlingStrategy":"validation","validationCode":"// Pre-build: ensure the entry imports at most one CSS file.\nimport { readFileSync } from \"node:fs\";\nconst entry = readFileSync(\"src/index.ts\", \"utf8\");\nconst cssImports = entry.match(/^\\s*import\\s+[\"'].*\\.css[\"']/gm) ?? [];\nif (cssImports.length > 1) {\n  throw new Error(`Entry imports ${cssImports.length} CSS files; consolidate into one.`);\n}","typeGuard":"function entryHasAtMostOneStyle(importedCss: Iterable<string> | undefined): boolean {\n  const count = importedCss ? [...importedCss].length : 0;\n  return count <= 1;\n}","tryCatchPattern":null,"preventionTips":["Consolidate entry CSS into a single file using @import or @layer.","Set build.cssCodeSplit: false for the ESM build so Vite emits one stylesheet.","Audit third-party CSS imports that attach to the entry chunk."],"tags":["build","esm","css","manifest","bundler-kit"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}