{"record":{"id":"a97789443dc9d494","repo":"angular/components","slug":"connectedposition-invalid-property-value","errorCode":null,"errorMessage":"ConnectedPosition: Invalid ${property} \"${value}\". Expected \"top\", \"bottom\" or \"center\".","messagePattern":"ConnectedPosition: Invalid (.+?) \"(.+?)\"\\. Expected \"top\", \"bottom\" or \"center\"\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/cdk/overlay/position/connected-position.ts","lineNumber":108,"sourceCode":"/** The change event emitted by the strategy when a fallback position is used. */\nexport class ConnectedOverlayPositionChange {\n  constructor(\n    /** The position used as a result of this change. */\n    public connectionPair: ConnectionPositionPair,\n    /** @docs-private */\n    public scrollableViewProperties: ScrollingVisibility,\n  ) {}\n}\n\n/**\n * Validates whether a vertical position property matches the expected values.\n * @param property Name of the property being validated.\n * @param value Value of the property being validated.\n * @docs-private\n */\nexport function validateVerticalPosition(property: string, value: VerticalConnectionPos) {\n  if (value !== 'top' && value !== 'bottom' && value !== 'center') {\n    throw Error(\n      `ConnectedPosition: Invalid ${property} \"${value}\". ` +\n        `Expected \"top\", \"bottom\" or \"center\".`,\n    );\n  }\n}\n\n/**\n * Validates whether a horizontal position property matches the expected values.\n * @param property Name of the property being validated.\n * @param value Value of the property being validated.\n * @docs-private\n */\nexport function validateHorizontalPosition(property: string, value: HorizontalConnectionPos) {\n  if (value !== 'start' && value !== 'end' && value !== 'center') {\n    throw Error(\n      `ConnectedPosition: Invalid ${property} \"${value}\". ` +\n        `Expected \"start\", \"end\" or \"center\".`,\n    );","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/angular/components/blob/0411926e7d8ae06b32236ec1048a888cfad5abf2/src/cdk/overlay/position/connected-position.ts#L90-L126","documentation":"validateVerticalPosition checks that every vertical connection value in a ConnectedPosition (originY / overlayY) is one of 'top', 'bottom', or 'center'. An invalid string (typo, wrong casing, or bad runtime data) throws at position-strategy construction. This runs only in dev mode (ngDevMode guard at _validatePositions).","triggerScenarios":"Calling flexibleConnectedTo(positions) with a position object where originY or overlayY is misspelled, e.g. 'Top', 'middle', or a variable computed at runtime that isn't a valid VerticalConnectionPos.","commonSituations":"Building positions arrays dynamically from config/JSON; typos like 'middel' or 'top-left' placed into originY; mixing up which field is vertical (originX/overlayX) vs horizontal.","solutions":["Fix the position object so originY/overlayY are exactly 'top', 'bottom', or 'center' (lowercase).","Type the positions array as ConnectedPosition[] so TypeScript catches invalid literals at compile time.","Validate any user-supplied/config-driven position values before passing them to the strategy.","If you meant a horizontal value, put it in originX/overlayX ('start','end','center') not originY/overlayY."],"exampleFix":"// before\nconst pos = { originY: 'middle', overlayY: 'top', originX: 'start', overlayX: 'start' };\n// after\nconst pos: ConnectedPosition = { originY: 'center', overlayY: 'top', originX: 'start', overlayX: 'start' };","handlingStrategy":"validation","validationCode":"const VERTICAL = new Set(['top', 'bottom', 'center']);\nif (!VERTICAL.has(position.originY) || !VERTICAL.has(position.overlayY)) {\n  throw new Error(`originY/overlayY must be top|bottom|center, got ${position.originY}/${position.overlayY}`);\n}","typeGuard":"type VerticalConnectionPos = 'top' | 'bottom' | 'center';\nfunction isValidVertical(v: unknown): v is VerticalConnectionPos {\n  return v === 'top' || v === 'bottom' || v === 'center';\n}","tryCatchPattern":"try {\n  overlayRef = overlay.create({ positionStrategy: overlay.position().flexibleConnectedTo(origin).withPositions(positions) });\n} catch (e) {\n  if ((e as Error).message.includes('Expected \"top\", \"bottom\" or \"center\"')) {\n    console.error('Fix originY/overlayY values');\n  } else { throw e; }\n}","preventionTips":["Type positions arrays as ConnectedPosition[] for compile-time literal checks.","Never use CSS terms like 'middle' or 'left' in originY/originX fields.","Validate config/JSON-driven positions against allowlists at load time.","Keep a typed constant list of valid positions in your config layer."],"tags":["angular","cdk","overlay","positioning"],"backgroundTag":"invalid-position-value","analyzedSha":"0411926e7d8ae06b32236ec1048a888cfad5abf2","analyzedAt":"2026-08-31T11:58:23.400Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}