JetBrains/intellij-community · error · CodeGenerationException

Cannot bind: field is of primitive type:

Error message

Cannot bind: field is of primitive type: 

What it means

Thrown by AsmCodeGenerator.validateFieldClass during GUI-form bytecode instrumentation when a form component is bound to a field whose JVM type descriptor is not an object reference (Type.getSort() != Type.OBJECT). The forms compiler must inject code that assigns the instantiated component to the bound field, and a primitive (or array) field cannot hold a component reference. The message says 'primitive type' but the check actually rejects every non-OBJECT sort, including arrays and primitives.

Source

Thrown at java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java:825

    public Type getMainClassType() {
      return Type.getType("L" + myClassName + ";");
    }

    private void validateFieldBinding(LwComponent component, final InstrumentationClassFinder.PseudoClass componentClass) throws CodeGenerationException {
      String binding = component.getBinding();
      if (binding == null) return;

      validateFieldClass(binding, componentClass, component.getId());
    }

    private void validateFieldClass(String binding, InstrumentationClassFinder.PseudoClass componentClass, String componentId) throws CodeGenerationException {
      if (!myFieldDescMap.containsKey(binding)) {
        throw new CodeGenerationException(componentId, "Cannot bind: field does not exist: " + myClassToBind + "." + binding);
      }

      final Type fieldType = Type.getType(myFieldDescMap.get(binding));
      if (fieldType.getSort() != Type.OBJECT) {
        throw new CodeGenerationException(componentId, "Cannot bind: field is of primitive type: " + myClassToBind + "." + binding);
      }

      try {
        final InstrumentationClassFinder.PseudoClass fieldClass = myFinder.loadClass(fieldType.getClassName());
        if (!fieldClass.isAssignableFrom(componentClass)) {
          throw new CodeGenerationException(componentId, "Cannot bind: Incompatible types. Cannot assign " + componentClass.getName().replace('/', '.') + " to field " + myClassToBind + "." + binding);
        }
      }
      catch (ClassNotFoundException e) {
        throw new CodeGenerationException(componentId, "Class not found: " + fieldType.getClassName());
      }
      catch (IOException e) {
        throw new CodeGenerationException(componentId, e.getMessage(), e);
      }
    }

    private void generateBorder(final LwContainer container, final GeneratorAdapter generator, final int componentLocal) {
      final BorderType borderType = container.getBorderType();

View on GitHub (pinned to be881553f2)

Solutions

  1. Change the bound field in the class-to-bind to a reference type compatible with the component (e.g. 'javax.swing.JButton myField;' instead of a primitive or array).
  2. If the field type changed intentionally, re-open the form in the GUI designer, clear or re-point the binding, and rebuild so myFieldDescMap sees fresh field descriptors.
  3. Remove the binding attribute from the component in the .form XML if the field is no longer meant to hold the component.
  4. Run a full rebuild (Build > Rebuild Project) so the forms compiler instruments against current class files rather than stale ones.

Example fix

// before (class to bind)
private int myButton; // form binds component to 'myButton'

// after
private javax.swing.JButton myButton;
Defensive patterns

Strategy: validation

Validate before calling

// Before instrumenting, verify each binding's field is a reference type
for (Field f : classToBind.getDeclaredFields()) {
  if (bindings.contains(f.getName()) && (f.getType().isPrimitive() || f.getType().isArray())) {
    throw new IllegalStateException("Binding '" + f.getName() + "' must be a reference type, was: " + f.getType());
}

Try / catch

try { generator.compile(); } catch (CodeGenerationException e) { if (e.getMessage().contains("primitive type")) { /* fix field type, report component id */ } else throw e; }

Prevention

When it happens

Trigger: A .form file has a component with binding='myField' and the class-to-bind declares 'int myField', 'boolean myField', or an array type like 'JButton[] myField'. Instrumentation (AsmCodeGenerator) reads the field descriptor from myFieldDescMap, sees sort != OBJECT, and throws CodeGenerationException with the component id before any assignability check runs.

Common situations: Hand-editing a bound class after the form was designed (field refactored from JButton to a primitive/arrays); using the GUI designer's binding field editor against an outdated compiled class where the field signature is stale; forms compiled against an old class version during incremental builds.

Related errors


AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14). Data as JSON: /api/errors/246da3d6361b0137. Report an issue: GitHub.