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
- 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).
- 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.
- Remove the binding attribute from the component in the .form XML if the field is no longer meant to hold the component.
- 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
- Create bound fields via the GUI designer's 'Create Field' action so types always match the component.
- After refactoring bound classes, rebuild fully so the forms compiler sees current field descriptors.
- Never bind components to primitive or array-typed fields.
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
- Cannot bind: Incompatible types. Cannot assign
- No binding on root component of nested form
- Error loading nested form:
- Class not found:
- Unsupported class version error:
AI-assisted analysis of JetBrains/intellij-community@be881553f2 (2026-08-14).
Data as JSON: /api/errors/246da3d6361b0137.
Report an issue: GitHub.