apache/iceberg · error · IllegalStateException

Cannot bind constructors

Error message

Cannot bind constructors

What it means

A constructor handle produced by DynConstructors cannot be bound to a receiver instance — constructors are invoked with their arguments directly and are conceptually static. Calling bind(receiver) on such a handle throws this IllegalStateException by design.

Solutions

  1. Don't call bind() on constructor handles; invoke with newInstance(...) or newInstanceChecked(...) passing constructor arguments.
  2. Separate constructor lookups from method lookups so bind() is only called on genuine method handles.
  3. Check isStatic() before binding — constructor handles report isStatic() == true and cannot bind a receiver.
  4. If a receiver-ful call is intended, look up an instance method via DynMethods instead of DynConstructors.

Example fix

// before
DynMethods.UnboundMethod ctor = DynConstructors.builder().impl(Foo.class).build();
Foo f = ctor.bind(receiver).invoke();
// after
Foo f = DynConstructors.builder().impl(Foo.class).build().newInstance();
Defensive patterns

Strategy: type-guard

Validate before calling

DynMethods.UnboundMethod handle = /* looked up */;
if (handle.isStatic()) {
  // constructor or static handle: never call bind(receiver)
}

Type guard

boolean canBindReceiver(DynMethods.UnboundMethod m) { return !m.isStatic(); }

Try / catch

try {
  bound = handle.bind(receiver);
} catch (IllegalStateException e) {
  if (e.getMessage().equals("Cannot bind constructors")) {
    throw new IllegalStateException("Use newInstance(args) for constructor handles, not bind()", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Treating a DynConstructors handle like a DynMethods handle: holding a CtorHandle (as a DynMethods.UnboundMethod) and calling bind(obj) to attach a receiver instead of calling newInstance(args).

Common situations: Generic reflective-dispatch code written against DynMethods that was handed a constructor handle; mixing constructor and method lookups in one code path.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/d78a2106b741965f. Report an issue: GitHub.

Appendix: source

Thrown at common/src/main/java/org/apache/iceberg/common/DynConstructors.java:104

    @Override
    @SuppressWarnings("unchecked")
    public <R> R invoke(Object target, Object... args) {
      Preconditions.checkArgument(
          target == null, "Invalid call to constructor: target must be null");
      return (R) newInstance(args);
    }

    @Override
    @SuppressWarnings("unchecked")
    <R> R invokeChecked(Object target, Object... args) throws Exception {
      Preconditions.checkArgument(
          target == null, "Invalid call to constructor: target must be null");
      return (R) newInstanceChecked(args);
    }

    @Override
    public DynMethods.BoundMethod bind(Object receiver) {
      throw new IllegalStateException("Cannot bind constructors");
    }

    @Override
    public boolean isStatic() {
      return true;
    }

    @Override
    public String toString() {
      return getClass().getSimpleName() + "(constructor=" + ctor + ", class=" + constructed + ")";
    }
  }

  /**
   * Constructs a new builder for finding a constructor dynamically.
   *
   * @return a Builder for finding a constructor
   */

View on GitHub (pinned to 86d9c8fc54)