{"record":{"id":"6fb64f7d289fb31c","repo":"angular/components","slug":"yposition-value-must-be-either-above-or-below","errorCode":null,"errorMessage":"yPosition value must be either 'above' or below'.\n      Example: <mat-menu yPosition=\"above\" #menu=\"matMenu\"></mat-menu>","messagePattern":"yPosition value must be either 'above' or below'\\.\n      Example: <mat-menu yPosition=\"above\" #menu=\"matMenu\"></mat-menu>","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/material/menu/menu-errors.ts","lineNumber":25,"sourceCode":" */\n\n/**\n * Throws an exception for the case when menu's x-position value isn't valid.\n * In other words, it doesn't match 'before' or 'after'.\n * @docs-private\n */\nexport function throwMatMenuInvalidPositionX() {\n  throw Error(`xPosition value must be either 'before' or after'.\n      Example: <mat-menu xPosition=\"before\" #menu=\"matMenu\"></mat-menu>`);\n}\n\n/**\n * Throws an exception for the case when menu's y-position value isn't valid.\n * In other words, it doesn't match 'above' or 'below'.\n * @docs-private\n */\nexport function throwMatMenuInvalidPositionY() {\n  throw Error(`yPosition value must be either 'above' or below'.\n      Example: <mat-menu yPosition=\"above\" #menu=\"matMenu\"></mat-menu>`);\n}\n\n/**\n * Throws an exception for the case when a menu is assigned\n * to a trigger that is placed inside the same menu.\n * @docs-private\n */\nexport function throwMatMenuRecursiveError() {\n  throw Error(\n    `matMenuTriggerFor: menu cannot contain its own trigger. Assign a menu that is ` +\n      `not a parent of the trigger or move the trigger outside of the menu.`,\n  );\n}\n","sourceCodeStart":7,"sourceCodeEnd":40,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/material/menu/menu-errors.ts#L7-L40","documentation":"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.","triggerScenarios":"Setting <mat-menu yPosition=\"top\">, yPosition=\"bottom\", or a bound [yPosition]=\"expr\" evaluating to null/undefined/typo at change-detection time.","commonSituations":"Using CSS vocabulary instead of Material's; bound value arrives asynchronously (initial undefined); casing mismatch ('Above'); mixing up with overlay position strings from CDK.","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."],"exampleFix":"// before\n<mat-menu [yPosition]=\"pos\"> <!-- pos: 'top' | 'bottom' -->\n// after\n<mat-menu [yPosition]=\"pos === 'top' ? 'above' : 'below'\">","handlingStrategy":"validation","validationCode":"type MenuYPosition = 'above' | 'below';\nfunction isYPosition(v: unknown): v is MenuYPosition {\n  return v === 'above' || v === 'below';\n}\nconst y = isYPosition(config.y) ? config.y : 'below';\n// template: <mat-menu [yPosition]=\"y\">","typeGuard":"function isMenuYPosition(v: unknown): v is 'above' | 'below' {\n  return v === 'above' || v === 'below';\n}","tryCatchPattern":"try {\n  menu.yPosition = config.y as 'above' | 'below';\n} catch (e) {\n  if ((e as Error).message.includes('yPosition value must be')) {\n    console.warn(`Invalid yPosition \"${config.y}\", defaulting to 'below'`);\n    menu.yPosition = 'below';\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["angular-material","mat-menu","invalid-input"],"backgroundTag":"invalid-position-input","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}