bazelbuild/bazel · error · IllegalStateException

%s missing getStarlarkType(StarlarkSemantics) method

Error message

%s missing getStarlarkType(StarlarkSemantics) method

What it means

Every class annotated with @StarlarkBuiltin must implement StarlarkValue, which declares getStarlarkType(StarlarkSemantics). When CallUtils enables builtin auto-typing it reflectively looks up that method via clazz.getMethod("getStarlarkType", StarlarkSemantics.class); NoSuchMethodException is rethrown as this IllegalStateException naming the offending class.

Source

Thrown at src/main/java/net/starlark/java/eval/CallUtils.java:412

  /**
   * Returns true if a {@link StarlarkBuiltinAutoType} should be generated for the given class. This
   * is the case if the class is annotated as {@link StarlarkBuiltin}, and does not override {@link
   * StarlarkValue#getStarlarkType}.
   */
  private static boolean wantStarlarkBuiltinAutoType(Class<?> clazz) {
    if (StarlarkAnnotations.getStarlarkBuiltin(clazz) == null) {
      return false;
    }
    Method getter;
    try {
      // LINT.IfChange
      getter = clazz.getMethod("getStarlarkType", StarlarkSemantics.class);
      // LINT.ThenChange(//src/main/java/net/starlark/java/eval/StarlarkValue.java)
    } catch (NoSuchMethodException e) {
      // All StarlarkBuiltin-annotated classes must implement StarlarkValue and thus have a
      // getStarlarkType method.
      throw new IllegalStateException(
          String.format("%s missing getStarlarkType(StarlarkSemantics) method", clazz), e);
    }
    return getter.getDeclaringClass().equals(StarlarkValue.class);
  }

  /**
   * Certain Java classes/interfaces should be associated with a special fixed {@link StarlarkType}
   * instead of a generated {@link StarlarkBuiltinAutoType}. Returns that fixed {@link
   * StarlarkType}, or null otherwise.
   */
  @Nullable
  private static StarlarkType getFixedStarlarkType(Class<?> clazz) {
    @Nullable StarlarkBuiltin annotation = StarlarkAnnotations.getStarlarkBuiltin(clazz);
    if (annotation != null && annotation.isStructType()) {
      // Interpret com.google.devtools.build.lib.starlarkbuildapi.core.StructApi as a marker for
      // an arbitrary struct type.
      return Types.ANY_STRUCT;
    }

View on GitHub (pinned to e6e199d060)

Solutions

  1. Make the @StarlarkBuiltin-annotated class implement StarlarkValue (it then inherits or implements getStarlarkType(StarlarkSemantics)).
  2. If you implement it manually, match the exact signature: public StarlarkType getStarlarkType(StarlarkSemantics semantics).
  3. Align all starlark artifacts to one version so the interface definition is unique.
  4. Clean rebuild after upgrading the Starlark library.

Example fix

// before
@StarlarkBuiltin(name = "widget")
class Widget { ... } // not a StarlarkValue

// after
@StarlarkBuiltin(name = "widget")
class Widget implements StarlarkValue { ... }
Defensive patterns

Strategy: type-guard

Type guard

static boolean isValidBuiltinClass(Class<?> c) {
  return c.isAnnotationPresent(StarlarkBuiltin.class)
      && StarlarkValue.class.isAssignableFrom(c);
}

Prevention

When it happens

Trigger: Adding @StarlarkBuiltin to a class that does not implement StarlarkValue (directly or via an interface); implementing StarlarkValue from an older version whose getStarlarkType signature differs (parameter type changed to StarlarkSemantics in a newer release); mixing starlark jar versions so the interface in the class's hierarchy lacks the method.

Common situations: Upgrading the Starlark library where the StarlarkValue interface gained/changed getStarlarkType; annotating a plain data class to expose it to Starlark without implementing the value interface; duplicate starlark artifacts on the classpath with different interface definitions (guarded by the LINT.IfChange marker linking this code to StarlarkValue.java).

Related errors


AI-assisted analysis of bazelbuild/bazel@e6e199d060 (2026-08-14). Data as JSON: /api/errors/902547b178e027db. Report an issue: GitHub.