theonedev/onedev · error · org.apache.wicket.WicketRuntimeException

FormComponent has to be required when the type is primitive

Error message

FormComponent has to be required when the type is primitive class: {this}

What it means

FormComponent.setRequired(false) throws WicketRuntimeException when the component's type is a primitive class. A primitive-typed converter cannot produce null/absent values, so Wicket forbids declaring such a component optional — it must remain required to always yield a value.

Source

Thrown at server-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java:1103

	 *            The value
	 */
	public void setModelValue(final String[] value)
	{
		convertedInput = convertValue(value);
		updateModel();
	}

	/**
	 * Sets the required flag
	 * 
	 * @param required
	 * @return this for chaining
	 */
	public final FormComponent<T> setRequired(final boolean required)
	{
		if (!required && getType() != null && getType().isPrimitive())
		{
			throw new WicketRuntimeException(
					"FormComponent has to be required when the type is primitive class: " + this);
		}
		if (required != isRequired())
		{
			addStateChange();
		}
		setFlag(FLAG_REQUIRED, required);
		return this;
	}

	/**
	 * Sets the type that will be used when updating the model for this component. If no type is
	 * specified String type is assumed.
	 * 
	 * @param type
	 * @return this for chaining
	 */
	public FormComponent<T> setType(Class<?> type)

View on GitHub (pinned to d44925c47c)

Solutions

  1. Use the boxed wrapper type instead: setType(Integer.class) / Long.class etc., then setRequired(false) is allowed
  2. Keep the component required if the type must stay primitive
  3. Guard dynamic code: only call setRequired(false) when !getType().isPrimitive()
  4. Set the type before deciding requiredness so the constraint is evaluated with the final type

Example fix

// before
field.setType(int.class);
field.setRequired(false); // throws
// after
field.setType(Integer.class);
field.setRequired(false); // OK
Defensive patterns

Strategy: validation

Validate before calling

if (field.getType() != null && field.getType().isPrimitive() && !field.isRequired()) {
    // use boxed type or keep required before calling setRequired(false)
}

Try / catch

try {
    field.setRequired(false);
} catch (WicketRuntimeException e) {
    field.setType(boxedType(field.getType()));
    field.setRequired(false);
}

Prevention

When it happens

Trigger: Calling setRequired(false) on a component after setType(int.class) / Integer.TYPE or a primitive type; toggling required dynamically based on a condition without considering the configured type.

Common situations: Reusing a component whose type was set to a primitive; copy-pasting optional-field configuration onto a primitive-typed field; generic form-building code that unconditionally calls setRequired(false).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/fa4e5ae948da1169. Report an issue: GitHub.