theonedev/onedev · warning · IllegalStateException

Placeholder tag set on a component that is usually not rende

Error message

Placeholder tag set on a component that is usually not rendered into markup. Component id: %s, component tag: %s.

What it means

Analogous to the markup-id case: a placeholder tag (setRenderBodyOnly / placeholder type settings) was set on a component that is not rendered into markup. Wicket logs a warning and throws IllegalStateException when ExceptionSettings.NotRenderableErrorStrategy is THROW_EXCEPTION, because the placeholder directive can never take effect.

Source

Thrown at server-core/src/main/java/org/apache/wicket/Component.java:4102

				if (getFlag(FLAG_OUTPUT_MARKUP_ID))
				{
					String message = String.format("Markup id set on a component that is usually not rendered into markup. " +
					                               "Markup id: %s, component id: %s, component tag: %s.",
					                               getMarkupId(), componentId, tagName);
					if (notRenderableErrorStrategy == ExceptionSettings.NotRenderableErrorStrategy.THROW_EXCEPTION)
					{
						throw new IllegalStateException(message);
					}
					log.warn(message);
				}
				if (getFlag(FLAG_PLACEHOLDER))
				{
					String message = String.format(
							"Placeholder tag set on a component that is usually not rendered into markup. " +
							"Component id: %s, component tag: %s.", componentId, tagName);
					if (notRenderableErrorStrategy == ExceptionSettings.NotRenderableErrorStrategy.THROW_EXCEPTION)
					{
						throw new IllegalStateException(message);
					}
					log.warn(message);
				}
			}

			// Write the tag
			tag.writeOutput(getResponse(), !needToRenderTag(null),
				getMarkup().getMarkupResourceStream().getWicketNamespace());
		}
	}

	/**
	 * Replaces the body with the given one.
	 * 
	 * @param markupStream
	 *            The markup stream to replace the tag body in
	 * @param tag
	 *            The tag

View on GitHub (pinned to d44925c47c)

Solutions

  1. Remove the placeholder/body-only setting from the non-renderable component.
  2. Apply the setting to a parent container that is actually rendered.
  3. Set ExceptionSettings.NotRenderableErrorStrategy to LOG_WARNING if the behavior is intentional.

Example fix

// before
Label lbl = new Label("y", "v");
lbl.setRenderBodyOnly(true); // never rendered as tag
add(lbl);
// after
WebMarkupContainer box = new WebMarkupContainer("y");
box.setRenderBodyOnly(true);
box.add(new Label("inner", "v"));
add(box);
Defensive patterns

Strategy: validation

Validate before calling

// only set placeholder/body-only on components that render a tag
if (component instanceof WebMarkupContainer || component instanceof FormComponent) {
    component.setRenderBodyOnly(true);
}

Try / catch

try { component.setRenderBodyOnly(true); } catch (IllegalStateException e) { log.warn("component not renderable: {}", component.getId()); }

Prevention

When it happens

Trigger: Calling setRenderBodyOnly(true) or configuring a placeholder tag type on a component that never writes a tag (transparent resolver / border body), while NotRenderableErrorStrategy == THROW_EXCEPTION.

Common situations: Placeholder usage inside borders or wicket:container regions; applications tightening exception settings to catch render bugs; refactoring that moved a component into a non-rendered position while keeping placeholder settings.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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