{"record":{"id":"fa4e5ae948da1169","repo":"theonedev/onedev","slug":"formcomponent-has-to-be-required-when-the-type-is","errorCode":null,"errorMessage":"FormComponent has to be required when the type is primitive class: {this}","messagePattern":"FormComponent has to be required when the type is primitive class: (.+?)","errorType":"exception","errorClass":"org.apache.wicket.WicketRuntimeException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java","lineNumber":1103,"sourceCode":"\t *            The value\n\t */\n\tpublic void setModelValue(final String[] value)\n\t{\n\t\tconvertedInput = convertValue(value);\n\t\tupdateModel();\n\t}\n\n\t/**\n\t * Sets the required flag\n\t * \n\t * @param required\n\t * @return this for chaining\n\t */\n\tpublic final FormComponent<T> setRequired(final boolean required)\n\t{\n\t\tif (!required && getType() != null && getType().isPrimitive())\n\t\t{\n\t\t\tthrow new WicketRuntimeException(\n\t\t\t\t\t\"FormComponent has to be required when the type is primitive class: \" + this);\n\t\t}\n\t\tif (required != isRequired())\n\t\t{\n\t\t\taddStateChange();\n\t\t}\n\t\tsetFlag(FLAG_REQUIRED, required);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Sets the type that will be used when updating the model for this component. If no type is\n\t * specified String type is assumed.\n\t * \n\t * @param type\n\t * @return this for chaining\n\t */\n\tpublic FormComponent<T> setType(Class<?> type)","sourceCodeStart":1085,"sourceCodeEnd":1121,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/org/apache/wicket/markup/html/form/FormComponent.java#L1085-L1121","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Use the boxed wrapper type instead: setType(Integer.class) / Long.class etc., then setRequired(false) is allowed","Keep the component required if the type must stay primitive","Guard dynamic code: only call setRequired(false) when !getType().isPrimitive()","Set the type before deciding requiredness so the constraint is evaluated with the final type"],"exampleFix":"// before\nfield.setType(int.class);\nfield.setRequired(false); // throws\n// after\nfield.setType(Integer.class);\nfield.setRequired(false); // OK","handlingStrategy":"validation","validationCode":"if (field.getType() != null && field.getType().isPrimitive() && !field.isRequired()) {\n    // use boxed type or keep required before calling setRequired(false)\n}","typeGuard":null,"tryCatchPattern":"try {\n    field.setRequired(false);\n} catch (WicketRuntimeException e) {\n    field.setType(boxedType(field.getType()));\n    field.setRequired(false);\n}","preventionTips":["Prefer boxed types (Integer, Long) for optional form components","Set type before configuring requiredness","Guard generic form-building code that toggles required"],"tags":["wicket","form","type-conversion"],"backgroundTag":"invalid-state-transition","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}