withastro/astro · error · Error
Apps must default export an object with an id, and a name.
Error message
Apps must default export an object with an id, and a name.
What it means
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`.)
Source
Thrown at packages/astro/src/toolbar/vite-plugin-dev-toolbar.ts:96
`safeLoadPlugin(${JSON.stringify(
plugin,
)}, async () => (await import(${JSON.stringify(
typeof plugin === 'string' ? plugin : plugin.entrypoint.toString(),
)})).default, ${JSON.stringify(
typeof plugin === 'string' ? plugin : plugin.entrypoint.toString(),
)})`,
)
.join(',')}]));
};
async function safeLoadPlugin(appDefinition, importEntrypoint, entrypoint) {
try {
let app;
if (typeof appDefinition === 'string') {
app = await importEntrypoint();
if (typeof app !== 'object' || !app.id || !app.name) {
throw new Error("Apps must default export an object with an id, and a name.");
}
} else {
app = appDefinition;
if (typeof app !== 'object' || !app.id || !app.name || !app.entrypoint) {
throw new Error("Apps must be an object with an id, a name and an entrypoint.");
}
const loadedApp = await importEntrypoint();
if (typeof loadedApp !== 'object') {
throw new Error("App entrypoint must default export an object.");
}
app = { ...app, ...loadedApp };
}
return app;View on GitHub (pinned to d081033d5f)
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.
Example fix
// before — entrypoint has no valid default export
// src/my-app.ts
export function init() {}
// after
// src/my-app.ts
export default {
id: 'my-app',
name: 'My App',
// ...app implementation
}; Defensive patterns
Strategy: validation
Validate before calling
// Validate a toolbar app's default export shape before registration
interface ToolbarApp { id: string; name: string; entrypoint?: string }
function assertToolbarApp(mod: unknown): asserts mod is ToolbarApp {
if (typeof mod !== 'object' || mod === null || !('id' in mod) || !('name' in mod)) {
throw new Error('Toolbar app must default export an object with id and name');
}
} Type guard
const isToolbarApp = (m: unknown): m is ToolbarApp => typeof m === 'object' && m !== null && typeof (m as any).id === 'string' && typeof (m as any).name === 'string';
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ${packageName} doesn't appear to be an integration or an ada
- PluginContentImportsError
- NoMatchingRenderer
- Apps must be an object with an id, a name and an entrypoint.
- App entrypoint must default export an object.
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/6a274a24aebb7c16.
Report an issue: GitHub.