ionic-team/ionic-framework · error · Error

"${side}" is not a valid value for [side]. Use "start" or "e

Error message

"${side}" is not a valid value for [side]. Use "start" or "end" instead.

What it means

Thrown by isEndSide() in helpers.ts when the `side` argument is neither 'start' nor 'end'. isEndSide maps a logical side to a physical one based on document.dir (RTL), and only the two logical sides are meaningful. The Side type already restricts the value at compile time, so a runtime hit means the type was bypassed.

Source

Thrown at core/src/utils/helpers.ts:332

  return { x: 0, y: 0 };
};

/**
 * @hidden
 * Given a side, return if it should be on the end
 * based on the value of dir
 * @param side the side
 * @param isRTL whether the application dir is rtl
 */
export const isEndSide = (side: Side): boolean => {
  const isRTL = document.dir === 'rtl';
  switch (side) {
    case 'start':
      return isRTL;
    case 'end':
      return !isRTL;
    default:
      throw new Error(`"${side}" is not a valid value for [side]. Use "start" or "end" instead.`);
  }
};

export const deferEvent = (event: EventEmitter): EventEmitter => {
  return debounceEvent(event, 0);
};

export const debounceEvent = (event: EventEmitter, wait: number): EventEmitter => {
  const original = (event as any)._original || event;
  return {
    _original: event,
    emit: debounce(original.emit.bind(original), wait),
  } as EventEmitter;
};

export const debounce = (func: (...args: any[]) => void, wait = 0) => {
  let timer: any;
  return (...args: any[]): any => {

View on GitHub (pinned to 625f9c38ad)

Solutions

  1. Only ever assign 'start' or 'end' to side props; map 'left'/'right' in your own code before binding.
  2. Validate user-supplied side values against ['start','end'] and default to 'start'.
  3. Remove `as Side` / `as any` casts on side and let TypeScript enforce the union.
  4. If you control the data source, store sides as the literal union.

Example fix

// before
const side = (userPref as any) as Side; // 'left' slips through
isEndSide(side);

// after
const side: Side = userPref === 'end' ? 'end' : 'start';
isEndSide(side);
Defensive patterns

Strategy: type-guard

Validate before calling

const VALID_SIDES = ['start','end'] as const;
function normalizeSide(s: unknown): Side {
  return s === 'end' ? 'end' : 'start';
}

Type guard

function isSide(v: unknown): v is Side {
  return v === 'start' || v === 'end';
}

Prevention

When it happens

Trigger: isEndSide is called with a value outside the union - e.g. 'left', 'right', an empty string, or undefined - typically because a component prop was bound to an unvalidated string or cast with `as Side` / `as any`.

Common situations: Binding [side] on ion-menu or ion-item-options to a free-form string; reading side from a config/URL and forwarding it without validation; third-party wrappers that accept 'left'/'right' and pass them through.

Related errors


AI-assisted analysis of ionic-team/ionic-framework@625f9c38ad (2026-08-12). Data as JSON: /api/errors/99f80f8d1be2ef70. Report an issue: GitHub.