emberjs/ember.js · error · Error
Defining a route serializer on route '${name}' outside an En
Error message
Defining a route serializer on route '${name}' outside an Engine is not allowed. What it means
In Ember's routing DSL, a custom serialize function may only be defined for routes inside an Engine (where it feeds addRouteForEngine). Defining serialize on a normal route map entry outside an engine is invalid because top-level routes serialize via the route's own serialize hook, so the DSL throws.
Source
Thrown at packages/@ember/routing/lib/dsl.ts:148
url: string,
name: string,
callback?: MatchCallback,
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
serialize?: (model: {}, params: string[]) => { [key: string]: unknown | undefined }
): void {
let parts = name.split('.');
if (this.options.engineInfo) {
let localFullName = name.slice(this.options.engineInfo.fullName.length + 1);
let routeInfo: EngineRouteInfo = Object.assign({ localFullName }, this.options.engineInfo);
if (serialize) {
routeInfo.serializeMethod = serialize;
}
this.options.addRouteForEngine(name, routeInfo);
} else if (serialize) {
throw new Error(
`Defining a route serializer on route '${name}' outside an Engine is not allowed.`
);
}
if (url === '' || url === '/' || parts[parts.length - 1] === 'index') {
this.explicitIndex = true;
}
this.matches.push(url, name, callback);
}
generate(): MatchCallback {
let dslMatches = this.matches;
if (!this.explicitIndex) {
this.route('index', { path: '/' });
}
View on GitHub (pinned to 26f97246a8)
Solutions
- Remove the serialize option and define serialize as a method on the Route class instead
- Only pass serialize for routes registered via addRouteForEngine inside engines
- Move the route into an engine if engine-specific serialization is required
Example fix
// before
this.route('post', { serialize: mySerializer });
// after
this.route('post');
// and in the route:
// export default class PostRoute extends Route { serialize(model) { return { id: model.id }; } } Defensive patterns
Strategy: validation
Validate before calling
if (serialize && !isEngineContext) { throw new Error('serialize option only allowed inside engines'); } Type guard
function canPassSerialize(dslOptions) { return typeof dslOptions.addRouteForEngine === 'function'; } Try / catch
try { buildRouteMap(dsl); } catch (e) { if (/route serializer .* outside an Engine/.test(e.message)) stripSerializeOptionsAndRebuild(); else throw e; } Prevention
- Put custom serialization on the Route class, not the DSL options
- Use the serialize option only for engine-registered routes
- Keep engine DSL helpers separate from app route maps
When it happens
Trigger: Using dsl.route('path', { serialize: fn }) (via mount/branch APIs) where the dsl is not an engine context — i.e. options.addRouteForEngine is absent and serialize was supplied to push().
Common situations: Passing a serialize option when manually building a route map or in addons that manipulate the DSL; code written for ember-engines reused in a non-engine app.
Related errors
- Defining a custom serialize method on an Engine route is not
- You attempted to mount the engine '${name}', but it is not r
- Programmatic transitions by URL cannot be used within an Eng
- More context objects were passed than there are dynamic segm
- You didn't provide enough string/numeric parameters to satis
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/75e39be550dabaaf.
Report an issue: GitHub.