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

  1. Set originX/overlayX to exactly 'start', 'end', or 'center'.
  2. Annotate the array as ConnectedPosition[] so invalid literals fail typechecking.
  3. Normalize RTL logic via the strategy's built-in handling rather than swapping in 'left'/'right' values.
  4. 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

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


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/953cd79a3e35813a. Report an issue: GitHub.