withastro/astro · error · Error
Apps must be an object with an id, a name and an entrypoint.
Error message
Apps must be an object with an id, a name and an entrypoint.
What it means
Thrown by the Astro dev toolbar Vite plugin when a registered toolbar app is provided as an object (the structured form) but is missing one of the three required fields: `id`, `name`, or `entrypoint`. The object form is the alternative to passing a bare entrypoint string; it lets you declare metadata separately from the entrypoint module. All three fields are mandatory in this form because the toolbar needs the id and name before the entrypoint is even imported.
Source
Thrown at packages/astro/src/toolbar/vite-plugin-dev-toolbar.ts:102
)})`,
)
.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;
} catch (err) {
console.error(\`Failed to load dev toolbar app from \${entrypoint}: \${err.message}\`);
if (import.meta.hot) {
import.meta.hot.send('astro:devtoolbar:error:load', { entrypoint: entrypoint, error: err.message })
}View on GitHub (pinned to d081033d5f)
Solutions
- Ensure the object passed to addDevToolbarApp includes all three keys: { id: 'my-app', name: 'My App', entrypoint: 'virtual:my-app' }.
- If you only have an entrypoint module that default-exports { id, name }, pass it as a plain string instead of an object — the string branch only requires id and name on the exported object.
- Check that `id` is a non-empty unique string and `name` is a non-empty human-readable string; falsy values (empty string, 0) fail the guard.
Example fix
// before
astroConfig.devToolbarApps = [{ id: 'myapp', name: 'My App' }];
// after
astroConfig.devToolbarApps = [{ id: 'myapp', name: 'My App', entrypoint: '/src/toolbar/myapp.ts' }]; Defensive patterns
Strategy: validation
Validate before calling
function isValidToolbarApp(app) {
if (typeof app === 'string') return app.length > 0;
return typeof app === 'object' && app !== null
&& typeof app.id === 'string' && app.id.length > 0
&& typeof app.name === 'string' && app.name.length > 0
&& (typeof app.entrypoint === 'string' || app.entrypoint instanceof URL);
}
if (!isValidToolbarApp(myApp)) throw new Error('Invalid toolbar app shape'); Type guard
function isToolbarAppObject(app): app is { id: string; name: string; entrypoint: string | URL } {
return typeof app === 'object' && app !== null
&& typeof app.id === 'string' && typeof app.name === 'string'
&& (typeof app.entrypoint === 'string' || app.entrypoint instanceof URL);
} Prevention
- Always specify id, name, AND entrypoint when using the object form for addDevToolbarApp.
- Prefer the string shorthand when the entrypoint module itself exports id and name.
- Add a unit test asserting your integration's devToolbarApps array passes a shape validator.
When it happens
Trigger: Calling `addDevToolbarApp()` (or configuring `devToolbarApps`) with an object like `{ id: 'x' }`, `{ id: 'x', name: 'Y' }` (no entrypoint), or `{ name: 'Y', entrypoint: '/path' }` (no id). The check runs at toolbar-app load time inside the generated `safeLoadPlugin` virtual module: `typeof app !== 'object' || !app.id || !app.name || !app.entrypoint`.
Common situations: Writing a custom dev toolbar app integration and forgetting the `entrypoint` field (most common omission, since id/name feel obvious). Migrating an app from the string shorthand to the object form and dropping a field. Typos in field names (e.g. `entry` instead of `entrypoint`).
Related errors
- App entrypoint must default export an object.
- Invalid quality for picture "${options.src}"
- UNSUPPORTED_MEDIA_TYPE
- BAD_REQUEST
- CannotExtractFontType
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/9de6456ba99020af.
Report an issue: GitHub.