withastro/astro · error · TypeError
Expected `server` export in actions file to be an object. Re
Error message
Expected `server` export in actions file to be an object. Received ${typeof server}. What it means
A `TypeError` thrown when the actions module's `server` export is falsy or not an object. `getAction` calls `this.getActions()` and destructures `{ server }`; if `server` is null, undefined, or a non-object type, the guard `!server || typeof server !== 'object'` triggers. This means the `src/actions/index.*` file doesn't correctly export a `server` object.
Source
Thrown at packages/astro/src/core/base-pipeline.ts:371
}
async getServerIslands(): Promise<ServerIslandMappings> {
if (this.serverIslands) {
return this.serverIslands();
}
return {
serverIslandMap: new Map(),
serverIslandNameMap: new Map(),
};
}
async getAction(path: string): Promise<ActionClient<unknown, ActionAccept, $ZodType>> {
const pathKeys = path.split('.').map((key) => decodeURIComponent(key));
let { server } = await this.getActions();
if (!server || !(typeof server === 'object')) {
throw new TypeError(
`Expected \`server\` export in actions file to be an object. Received ${typeof server}.`,
);
}
for (const key of pathKeys) {
// An action is a leaf: once resolved to a function, its own properties
// are not part of the action namespace and cannot be traversed further.
if (typeof server === 'function') {
throw new AstroError({
...ActionNotFoundError,
message: ActionNotFoundError.message(pathKeys.join('.')),
});
}
if (FORBIDDEN_PATH_KEYS.has(key)) {
throw new AstroError({
...ActionNotFoundError,
message: ActionNotFoundError.message(pathKeys.join('.')),
});View on GitHub (pinned to d081033d5f)
Solutions
- Ensure `src/actions/index.ts` exports `server` as an object containing action handlers.
- Use the `defineActions` or correct export pattern: `export const server = { ... }`.
- Check for TypeScript or syntax errors in the actions file.
- Verify you're on the correct Astro version for your Actions API usage.
Example fix
// before — src/actions/index.ts
export const myAction = async (input) => { ... };
// after
import { defineAction } from 'astro:actions';
export const server = {
myAction: defineAction({
input: z.string(),
handler: async (input) => { ... },
}),
}; Defensive patterns
Strategy: type-guard
Validate before calling
import type { server } from './src/actions/index';
// TypeScript will error if 'server' is missing or wrong type at build time Type guard
function isValidServerExport(server: unknown): server is Record<string, unknown> {
return typeof server === 'object' && server !== null && !Array.isArray(server);
} Prevention
- Always use the canonical Actions export pattern: export const server = { ... }.
- Run astro check to validate the actions module at type level.
- Keep the actions file simple — only export server.
When it happens
Trigger: The actions file (`src/actions/index.ts`) either doesn't export `server`, exports it as a non-object (function, string, etc.), or the module failed to load and `server` is undefined. `getAction` is called (e.g. via `Astro.callAction` or RPC), destructures `{ server }`, and the typeof check fails.
Common situations: The actions file exports actions at the top level instead of nested under `server`. Using the old Actions API format after upgrading. The actions file has a syntax error causing it to export nothing. An integration or custom setup replaces the actions module incorrectly.
Related errors
- Expected handler for action ${pathKeys.join('.')} to be a fu
- ActionCalledFromServerError
- ActionCalledFromServerError
- [astro:actions] `defineAction()` unexpectedly used on the cl
- [astro:actions] `getActionContext()` unexpectedly used on th
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/03d7f13f63881a03.
Report an issue: GitHub.