theonedev/onedev · error · WicketRuntimeException
Wicket Session object not available
Error message
Wicket Session object not available
What it means
Wicket throws this WicketRuntimeException when code on a Component calls getSession() and no Session object is bound to the current thread/request context. Wicket components require an active RequestCycle with a bound Session to resolve things like style, locale, and page state. Calling component APIs outside the request processing thread (or after the session expired) leaves no session available.
Solutions
- Run the component code inside the Wicket request thread (request cycle) where a Session is bound.
- If work must happen off-thread, capture needed values (locale, style) on the request thread first, or use a Session-bound approach like running code via the page's scheduler.
- In tests, use WicketTester which establishes a session; don't instantiate components directly.
- Check that the session hasn't expired (session timeout) before touching components.
- Refactor to not depend on Session for background logic — pass explicit parameters instead.
Example fix
// before
executor.submit(() -> {
label.setDefaultModelObject(loadData()); // touches getSession()
});
// after
executor.submit(() -> {
Object data = loadData(sessionLocale, sessionStyle); // captured on request thread
target.getPage(); // update via AjaxRequestTarget on request thread
}); Defensive patterns
Strategy: try-catch
Validate before calling
if (RequestCycle.get() == null || Session.exists() == false) { throw new IllegalStateException("No Wicket session on this thread"); } Type guard
function hasWicketSession() { return org.apache.wicket.Session.exists(); } Try / catch
try { component.getStyle(); } catch (WicketRuntimeException e) { log.warn("No session bound; skipping style-dependent logic"); } Prevention
- Never call component APIs from non-request threads
- Use WicketTester in unit tests to establish a session
- Capture session-derived values (locale/style) early and pass them explicitly
When it happens
Trigger: Calling component methods that touch Session (e.g. getStyle(), getString(), getSession()-dependent logic) from a background/worker thread, a custom thread pool, a scheduled job, or a deserialization/initialization path outside a Wicket request cycle; also accessing a detached component after the session expired.
Common situations: Running Wicket logic in executor threads spawned by an IJob or daemon service; unit tests constructing components without a WebApplication/tester session; accessing components stored statically; calling getStyle() during Application init before any request exists.
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
- An error occurred while detaching component:
- Cannot determine Markup. Component is not yet connected to…
- Cannot modify component hierarchy after render phase has…
- Cannot remove
- has not been properly added. Something in the hierarchy of
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/18a3b31a15808077.
Report an issue: GitHub.
Appendix: source
Thrown at server-core/src/main/java/org/apache/wicket/Component.java:1943
*/
public final String getString(final String key, final IModel<?> model, final String defaultValue)
{
return getLocalizer().getString(key, this, model, defaultValue);
}
/**
* A convenience method to access the Sessions's style.
*
* @return The style of this component respectively the style of the Session.
*
* @see org.apache.wicket.Session#getStyle()
*/
public final String getStyle()
{
Session session = getSession();
if (session == null)
{
throw new WicketRuntimeException("Wicket Session object not available");
}
return session.getStyle();
}
/**
* Gets the variation string of this component that will be used to look up markup for this
* component. Subclasses can override this method to define by an instance what markup variation
* should be picked up. By default it will return null or the value of a parent.
*
* @return The variation of this component.
*/
public String getVariation()
{
if (parent != null)
{
return parent.getVariation();
}
return null;View on GitHub (pinned to d44925c47c)