angular/components · error
xPosition value must be either 'before' or after'. Exa
Error message
xPosition value must be either 'before' or after'.
Example: <mat-menu xPosition="before" #menu="matMenu"></mat-menu> What it means
MatMenu validates the xPosition input against 'before' | 'after'. Any other value makes the positioning math invalid, so the xPosition setter calls throwMatMenuInvalidPositionX, whose message (noting the missing opening quote on "after'") shows usage.
Source
Thrown at src/material/menu/menu-errors.ts:15
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
/**
* Throws an exception for the case when menu's x-position value isn't valid.
* In other words, it doesn't match 'before' or 'after'.
* @docs-private
*/
export function throwMatMenuInvalidPositionX() {
throw Error(`xPosition value must be either 'before' or after'.
Example: <mat-menu xPosition="before" #menu="matMenu"></mat-menu>`);
}
/**
* Throws an exception for the case when menu's y-position value isn't valid.
* In other words, it doesn't match 'above' or 'below'.
* @docs-private
*/
export function throwMatMenuInvalidPositionY() {
throw Error(`yPosition value must be either 'above' or below'.
Example: <mat-menu yPosition="above" #menu="matMenu"></mat-menu>`);
}
/**
* Throws an exception for the case when a menu is assigned
* to a trigger that is placed inside the same menu.
* @docs-private
*/View on GitHub (pinned to 0411926e7d)
Solutions
- Use xPosition="before" or xPosition="after" literally.
- For bound values, constrain the type: xPosition: 'before' | 'after' and guard config defaults (xPosition ?? 'after').
- Validate external config before passing into the template.
Example fix
// before <mat-menu [xPosition]="menu.x"></mat-menu> <!-- menu.x = 'left' --> // after <mat-menu [xPosition]="menu.x === 'left' ? 'before' : 'after'"></mat-menu>
Defensive patterns
Strategy: validation
Validate before calling
type MenuXPosition = 'before' | 'after';
function isXPosition(v: unknown): v is MenuXPosition {
return v === 'before' || v === 'after';
}
const x = isXPosition(config.x) ? config.x : 'after';
// template: <mat-menu [xPosition]="x"> Type guard
function isMenuXPosition(v: unknown): v is 'before' | 'after' {
return v === 'before' || v === 'after';
} Try / catch
try {
menu.xPosition = config.x as 'before' | 'after';
} catch (e) {
if ((e as Error).message.includes('xPosition value must be')) {
console.warn(`Invalid xPosition "${config.x}", defaulting to 'after'`);
menu.xPosition = 'after';
} else { throw e; }
} Prevention
- Use only 'before'/'after' — not 'left'/'right'
- Provide defaults for async-bound values: config.x ?? 'after'
- Type config fields as 'before' | 'after' so TS rejects invalid values
When it happens
Trigger: Setting <mat-menu xPosition="left">, xPosition="right", or a bound [xPosition]="expr" where expr is null/undefined/typo.
Common situations: Typing CSS-like values ('left'/'right') instead of Material's vocabulary; binding from config data that defaults to null before load; renaming refactor that introduced casing mismatch ('Before').
Related errors
- yPosition value must be either 'above' or below'. Exam
- Invalid value "${this.fixedRowHeight}" set as rowHeight.
- mat-grid-list: invalid ratio given for row-height: "${value}
- matMenuTriggerFor: menu cannot contain its own trigger. Assi
- mat-tab-group background color must be set through the Sass
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/a2d689a93c6c1e9b.
Report an issue: GitHub.