theonedev/onedev · error · WicketRuntimeException
Cannot modify component hierarchy after render phase has sta
Error message
Cannot modify component hierarchy after render phase has started (page version cant change then anymore)
What it means
checkHierarchyChange() throws WicketRuntimeException when code tries to add/remove/replace components while the page is being rendered (FLAG_RENDERING is set) and the component is not auto-added. Once rendering started, the page version is committed and structural changes would corrupt the rendered output, so Wicket forbids them.
Source
Thrown at server-core/src/main/java/org/apache/wicket/Component.java:3680
findMarkupStream().throwMarkupException(msg);
}
}
}
/**
* Checks whether the hierarchy may be changed at all, and throws an exception if this is not
* the case.
*
* @param component
* the component which is about to be added or removed
*/
protected void checkHierarchyChange(final Component component)
{
// Throw exception if modification is attempted during rendering
if (getFlag(FLAG_RENDERING) && !component.isAuto())
{
throw new WicketRuntimeException(
"Cannot modify component hierarchy after render phase has started (page version cant change then anymore)");
}
}
/**
* Detaches the model for this component if it is detachable.
*/
protected void detachModel()
{
IModel<?> model = getModelImpl();
if (model != null)
{
model.detach();
}
// also detach the wrapped model of a component assigned wrap (not
// inherited)
if (model instanceof IWrapModel && !getFlag(FLAG_INHERITABLE_MODEL))
{View on GitHub (pinned to d44925c47c)
Solutions
- Move hierarchy changes earlier in the lifecycle: constructor, onInitialize, or onBeforeRender before the render flag is set.
- If the change must happen during render, mark the component auto-added (component.setAuto(true)) or pre-build children in onInitialize.
- Use AJAX mechanisms (target.add / add children before rendering) instead of mutating the hierarchy mid-render.
- Check for accidental render-time mutation, e.g. calling add() inside renderHead or onRender.
Example fix
// before
@Override
protected void onBeforeRender() {
add(new Label("extra")); // may run after render started
super.onBeforeRender();
}
// after
@Override
protected void onInitialize() {
super.onInitialize();
add(new Label("extra")); // safe: before render phase
} Defensive patterns
Strategy: validation
Validate before calling
if (component.getPage() != null && component.findParent(Page.class) != null && component.isPreparedForRender()) {
throw new IllegalStateException("too late to modify hierarchy");
} Try / catch
try { parent.add(child); } catch (WicketRuntimeException e) { target.add(parent); // or restructure to build children in onInitialize } Prevention
- Create and add child components in constructors or onInitialize, never in onRender/renderHead.
- Use ListView/RepeatingView for dynamic children instead of add() at render time.
- Enable Component.checksAreOn during development to catch lifecycle misuse early.
When it happens
Trigger: Calling add(), remove(), replace() or similar hierarchy mutations from code that runs during rendering: onBeforeRender of a sibling, during renderHead, inside render of another component, or from behaviors rendering late.
Common situations: Dynamically adding components in onBeforeRender after render phase began; updating a ListView during rendering; adding components from an AJAX request handler that runs mid-render; page-relative lazy initialization done too late.
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
- Cannot determine Markup. Component is not yet connected to a
- has not been properly initialized. Something in the hierarc
- has not been properly added. Something in the hierarchy of
- has not been properly detached. Something in the hierarchy
- has not been properly rendered. Something in the hierarchy
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/4aa504720e948b4b.
Report an issue: GitHub.