{"record":{"id":"6a274a24aebb7c16","repo":"withastro/astro","slug":"apps-must-default-export-an-object-with-an-id-and","errorCode":null,"errorMessage":"Apps must default export an object with an id, and a name.","messagePattern":"Apps must default export an object with an id, and a name\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/toolbar/vite-plugin-dev-toolbar.ts","lineNumber":96,"sourceCode":"\t\t\t\t\t\t\t\t\t\t`safeLoadPlugin(${JSON.stringify(\n\t\t\t\t\t\t\t\t\t\t\tplugin,\n\t\t\t\t\t\t\t\t\t\t)}, async () => (await import(${JSON.stringify(\n\t\t\t\t\t\t\t\t\t\t\ttypeof plugin === 'string' ? plugin : plugin.entrypoint.toString(),\n\t\t\t\t\t\t\t\t\t\t)})).default, ${JSON.stringify(\n\t\t\t\t\t\t\t\t\t\t\ttypeof plugin === 'string' ? plugin : plugin.entrypoint.toString(),\n\t\t\t\t\t\t\t\t\t\t)})`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.join(',')}]));\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tasync function safeLoadPlugin(appDefinition, importEntrypoint, entrypoint) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tlet app;\n\t\t\t\t\t\t\t\tif (typeof appDefinition === 'string') {\n\t\t\t\t\t\t\t\t\tapp = await importEntrypoint();\n\n\t\t\t\t\t\t\t\t\tif (typeof app !== 'object' || !app.id || !app.name) {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Apps must default export an object with an id, and a name.\");\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tapp = appDefinition;\n\n\t\t\t\t\t\t\t\t\tif (typeof app !== 'object' || !app.id || !app.name || !app.entrypoint) {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"Apps must be an object with an id, a name and an entrypoint.\");\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tconst loadedApp = await importEntrypoint();\n\n\t\t\t\t\t\t\t\t\tif (typeof loadedApp !== 'object') {\n\t\t\t\t\t\t\t\t\t\tthrow new Error(\"App entrypoint must default export an object.\");\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tapp = { ...app, ...loadedApp };\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn app;","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/toolbar/vite-plugin-dev-toolbar.ts#L78-L114","documentation":"The dev-toolbar Vite plugin loads each registered toolbar app. When an app is registered by string entrypoint, Astro dynamically imports it and expects the module to default-export an object containing at least `id` and `name`. If the imported value is not an object, or lacks `id`/`name`, the plugin throws inside the dev server so the author fixes the app's contract. (The object-form registration additionally requires `entrypoint`.)","triggerScenarios":"A toolbar app entrypoint module has no default export, exports a non-object, or its default export is missing `id` or `name`; an integration's `addClientDirective`/toolbar registration points at the wrong file; the entrypoint throws during import so its default resolves to undefined.","commonSituations":"Authoring a custom dev-toolbar app/integration and forgetting the required export shape; pointing the app entrypoint at a non-app module; integration misconfiguration during local development.","solutions":["Make the entrypoint default-export an object with `id` and `name` (string form), e.g. `export default { id: 'my-app', name: 'My App', ... }`.","If registering via the object form, also include `entrypoint`.","Verify the entrypoint path resolves to the intended module and that the module loads without error."],"exampleFix":"// before — entrypoint has no valid default export\n// src/my-app.ts\nexport function init() {}\n\n// after\n// src/my-app.ts\nexport default {\n  id: 'my-app',\n  name: 'My App',\n  // ...app implementation\n};","handlingStrategy":"validation","validationCode":"// Validate a toolbar app's default export shape before registration\ninterface ToolbarApp { id: string; name: string; entrypoint?: string }\nfunction assertToolbarApp(mod: unknown): asserts mod is ToolbarApp {\n  if (typeof mod !== 'object' || mod === null || !('id' in mod) || !('name' in mod)) {\n    throw new Error('Toolbar app must default export an object with id and name');\n  }\n}","typeGuard":"const isToolbarApp = (m: unknown): m is ToolbarApp =>\n  typeof m === 'object' && m !== null && typeof (m as any).id === 'string' && typeof (m as any).name === 'string';","tryCatchPattern":null,"preventionTips":["Default-export `{ id, name }` (and `entrypoint` for object-form registration) from every toolbar app.","Point app registrations at the correct module path.","Confirm the entrypoint imports without errors during dev."],"tags":["dev-toolbar","toolbar-apps","plugin","integration"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}