angular/components · error · Error
ConnectedPosition: Invalid ${property} "${value}". Expected
Error message
ConnectedPosition: Invalid ${property} "${value}". Expected "start", "end" or "center". What it means
validateHorizontalPosition checks that every horizontal connection value in a ConnectedPosition (originX / overlayX) is one of 'start', 'end', or 'center'. Anything else throws at strategy construction (dev mode only). It mirrors validateVerticalPosition for the horizontal axis.
Source
Thrown at src/cdk/overlay/position/connected-position.ts:123
*/
export function validateVerticalPosition(property: string, value: VerticalConnectionPos) {
if (value !== 'top' && value !== 'bottom' && value !== 'center') {
throw Error(
`ConnectedPosition: Invalid ${property} "${value}". ` +
`Expected "top", "bottom" or "center".`,
);
}
}
/**
* Validates whether a horizontal position property matches the expected values.
* @param property Name of the property being validated.
* @param value Value of the property being validated.
* @docs-private
*/
export function validateHorizontalPosition(property: string, value: HorizontalConnectionPos) {
if (value !== 'start' && value !== 'end' && value !== 'center') {
throw Error(
`ConnectedPosition: Invalid ${property} "${value}". ` +
`Expected "start", "end" or "center".`,
);
}
}
View on GitHub (pinned to 0411926e7d)
Solutions
- Set originX/overlayX to exactly 'start', 'end', or 'center'.
- Annotate the array as ConnectedPosition[] so invalid literals fail typechecking.
- Normalize RTL logic via the strategy's built-in handling rather than swapping in 'left'/'right' values.
- Validate config-provided values against an allowlist before constructing the strategy.
Example fix
// before
const pos = { originX: 'left', overlayX: 'right', originY: 'bottom', overlayY: 'top' };
// after
const pos: ConnectedPosition = { originX: 'start', overlayX: 'end', originY: 'bottom', overlayY: 'top' }; Defensive patterns
Strategy: validation
Validate before calling
const HORIZONTAL = new Set(['start', 'end', 'center']);
if (!HORIZONTAL.has(position.originX) || !HORIZONTAL.has(position.overlayX)) {
throw new Error(`originX/overlayX must be start|end|center, got ${position.originX}/${position.overlayX}`);
} Type guard
type HorizontalConnectionPos = 'start' | 'end' | 'center';
function isValidHorizontal(v: unknown): v is HorizontalConnectionPos {
return v === 'start' || v === 'end' || v === 'center';
} Try / catch
try {
overlayRef = overlay.create({ positionStrategy: overlay.position().flexibleConnectedTo(origin).withPositions(positions) });
} catch (e) {
if ((e as Error).message.includes('Expected "start", "end" or "center"')) {
console.error('Fix originX/overlayX values');
} else { throw e; }
} Prevention
- Use logical values 'start'/'end' rather than 'left'/'right'.
- Annotate positions as ConnectedPosition[] to catch bad literals at build time.
- Normalize any config values through a mapper before constructing strategies.
- Add unit tests enumerating all configured position combinations.
When it happens
Trigger: Passing a positions object to flexibleConnectedTo with originX or overlayX set to an invalid value like 'left', 'right', 'Left', or an undefined runtime variable.
Common situations: Using CSS vocabulary ('left'/'right') instead of the CDK's logical values ('start'/'end'); config-driven position maps containing legacy values; mixing RTL assumptions into the literal values.
Related errors
- ConnectedPosition: Invalid ${property} "${value}". Expected
- FlexibleConnectedPositionStrategy: At least one position is
- This position strategy is already attached to an overlay
- Scroll strategy has already been attached.
- Scroll strategy has already been attached.
AI-assisted analysis of angular/components@0411926e7d (2026-08-31).
Data as JSON: /api/errors/953cd79a3e35813a.
Report an issue: GitHub.