angular/components · error
yPosition value must be either 'above' or below'. Exam
Error message
yPosition value must be either 'above' or below'.
Example: <mat-menu yPosition="above" #menu="matMenu"></mat-menu> What it means
MatMenu validates yPosition against 'above' | 'below'. The yPosition setter calls throwMatMenuInvalidPositionY when the value differs, so the menu never renders with an ambiguous vertical placement.
Source
Thrown at src/material/menu/menu-errors.ts:25
*/
/**
* 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
*/
export function throwMatMenuRecursiveError() {
throw Error(
`matMenuTriggerFor: menu cannot contain its own trigger. Assign a menu that is ` +
`not a parent of the trigger or move the trigger outside of the menu.`,
);
}
View on GitHub (pinned to 0411926e7d)
Solutions
- Use yPosition="above" or yPosition="below".
- Default bound values: [yPosition]="config.y ?? 'below'".
- Type the config field as 'above' | 'below' so TypeScript catches invalid values at compile time.
Example fix
// before <mat-menu [yPosition]="pos"> <!-- pos: 'top' | 'bottom' --> // after <mat-menu [yPosition]="pos === 'top' ? 'above' : 'below'">
Defensive patterns
Strategy: validation
Validate before calling
type MenuYPosition = 'above' | 'below';
function isYPosition(v: unknown): v is MenuYPosition {
return v === 'above' || v === 'below';
}
const y = isYPosition(config.y) ? config.y : 'below';
// template: <mat-menu [yPosition]="y"> Type guard
function isMenuYPosition(v: unknown): v is 'above' | 'below' {
return v === 'above' || v === 'below';
} Try / catch
try {
menu.yPosition = config.y as 'above' | 'below';
} catch (e) {
if ((e as Error).message.includes('yPosition value must be')) {
console.warn(`Invalid yPosition "${config.y}", defaulting to 'below'`);
menu.yPosition = 'below';
} else { throw e; }
} Prevention
- Use only 'above'/'below' — not 'top'/'bottom'
- Default async-bound values: config.y ?? 'below'
- Type config fields as 'above' | 'below' to surface mistakes at compile time
When it happens
Trigger: Setting <mat-menu yPosition="top">, yPosition="bottom", or a bound [yPosition]="expr" evaluating to null/undefined/typo at change-detection time.
Common situations: Using CSS vocabulary instead of Material's; bound value arrives asynchronously (initial undefined); casing mismatch ('Above'); mixing up with overlay position strings from CDK.
Related errors
- xPosition value must be either 'before' or after'. Exa
- 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/6fb64f7d289fb31c.
Report an issue: GitHub.