ionic-team/ionic-framework · error · Error

invalid views to insert

Error message

invalid views to insert

What it means

Thrown in IonNav.prepareTI() when `convertToViews(insertViews)` returns an empty array. convertToViews builds ViewController instances from the supplied components; an empty result means none of the supplied items could be turned into a valid view (e.g. they were undefined/null/not a component). This guards the nav against inserting nothing on a push/insert/setRoot/setPages call.

Source

Thrown at core/src/components/nav/nav.tsx:731

    if (ti.insertViews) {
      // allow -1 to be passed in to auto push it on the end
      // and clean up the index if it's larger then the size of the stack
      if (ti.insertStart! < 0 || ti.insertStart! > viewsLength) {
        ti.insertStart = viewsLength;
      }
      ti.enteringRequiresTransition = ti.insertStart === viewsLength;
    }

    const insertViews = ti.insertViews;
    if (!insertViews) {
      return;
    }
    assert(insertViews.length > 0, 'length can not be zero');
    const viewControllers = convertToViews(insertViews);

    if (viewControllers.length === 0) {
      throw new Error('invalid views to insert');
    }

    // Check all the inserted view are correct
    for (const view of viewControllers) {
      view.delegate = ti.opts.delegate;
      const nav = view.nav;
      if (nav && nav !== this) {
        throw new Error('inserted view was already inserted');
      }
      if (view.state === VIEW_STATE_DESTROYED) {
        throw new Error('inserted view was already destroyed');
      }
    }
    ti.insertViews = viewControllers;
  }

  /**
   * Returns the view that will be entered considering the transition instructions.

View on GitHub (pinned to 625f9c38ad)

Solutions

  1. Verify the component reference is defined at the call site (`console.assert(MyComponent)`).
  2. For dynamic imports, `await` them and confirm the resolved value before passing: `const C = (await import('./c')).default; if (C) nav.setRoot(C);`.
  3. If using setPages/insertPages, ensure every array entry is a valid component or `{ component, componentProps }` object.
  4. Check for circular imports that evaluate the component before it is assigned.

Example fix

// before
await nav.push(undefined);
// after
import { HomePage } from './home.page';
await nav.push(HomePage);
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the component is a valid, defined component before pushing
function isValidComponent(c: any): boolean {
  return c != null && (typeof c === 'function' || typeof c === 'object');
}
if (!isValidComponent(component)) {
  throw new Error(`Invalid component passed to nav: ${component}`);
}
await nav.push(component);

Type guard

function isNavComponent(c: any): boolean {
  return c != null && (typeof c === 'function' || (typeof c === 'object' && typeof c.prototype !== 'undefined'));
}

Try / catch

try {
  await nav.push(component);
} catch (e) {
  if ((e as Error).message === 'invalid views to insert') {
    console.error('Component could not be converted to a view:', component);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling `nav.push(component)`, `nav.insert(...)`, `nav.setRoot(component)`, or `nav.setPages([...])` with a component that is `undefined`, `null`, not a valid component reference, or an array whose entries all fail conversion.

Common situations: Passing a lazily-imported component that resolved to undefined (broken dynamic import); typo in a component reference; passing a string instead of a component class/element; tree-shaking stripping the component; circular import returning undefined at evaluation time.

Related errors


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