material-components/material-components-android · error · IllegalStateException

Demo must implement createFragment or createActivityIntent

Error message

Demo must implement createFragment or createActivityIntent

What it means

Demo.getDemoClassName() derives the demo's class name by first trying createFragment(), then createActivityIntent(). If a Demo subclass overrides neither (both return null by default), the method has no name to report and throws IllegalStateException. Every Demo must implement at least one of these factory methods.

Source

Thrown at catalog/java/io/material/catalog/feature/Demo.java:66

  }

  @Nullable
  public Intent createActivityIntent() {
    return null;
  }

  @NonNull
  public String getDemoClassName() {
    Fragment fragment = createFragment();
    if (fragment != null) {
      return fragment.getClass().getSimpleName();
    }
    Intent activityIntent = createActivityIntent();
    if (activityIntent != null) {
      String className = activityIntent.getComponent().getClassName();
      return className.substring(className.lastIndexOf('.') + 1);
    }
    throw new IllegalStateException("Demo must implement createFragment or createActivityIntent");
  }
}

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Override createFragment() in your Demo subclass to return your demo Fragment instance.
  2. If the demo is an Activity instead, override createActivityIntent() to return a non-null Intent for it.
  3. Ensure the override actually returns a non-null object in every code path (no conditional null returns).

Example fix

// before
class MyDemo extends Demo {
  // no factory method overridden -> IllegalStateException
}

// after
class MyDemo extends Demo {
  @Override
  public Fragment createFragment() {
    return new MyDemoFragment();
  }
}
Defensive patterns

Strategy: validation

Validate before calling

boolean valid = demo.createFragment() != null || demo.createActivityIntent() != null;
if (!valid) {
  throw new ConfigurationError(demo.getClass().getName() + " implements no factory method");
}

Prevention

When it happens

Trigger: Defining a Demo (or DemoLandingFragment Demo) subclass that overrides neither createFragment() nor createActivityIntent(), then the catalog calls getDemoClassName() on it (e.g. while building the demo list UI or logging analytics).

Common situations: Adding a new demo entry and forgetting to implement its factory method; refactoring a demo from a Fragment to an Activity and accidentally deleting both overrides; a Demo subclass whose createFragment() returns null because the fragment field was never set.

Related errors


AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14). Data as JSON: /api/errors/450a5aac96aa53ee. Report an issue: GitHub.