theonedev/onedev · error · IllegalArgumentException

Replacement component must have the same id as the component

Error message

Replacement component must have the same id as the component it will replace. Replacement id [[

What it means

Component.replaceWith() swaps this component for a replacement in the parent, and requires the replacement to have the identical component id (wicket:id). It throws IllegalArgumentException when replacement.getId() differs from this component's id, so that the parent's markup mapping stays consistent.

Source

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

	 * 
	 * and provides a better context for errors.
	 * <p>
	 * Usage: <code>component = component.replaceWith(replacement);</code>
	 * </p>
	 * 
	 * @since 1.2.1
	 * 
	 * @param replacement
	 *            component to replace this one
	 * @return the component which replaced this one
	 */
	public Component replaceWith(Component replacement)
	{
		Args.notNull(replacement, "replacement");

		if (!getId().equals(replacement.getId()))
		{
			throw new IllegalArgumentException(
				"Replacement component must have the same id as the component it will replace. Replacement id [[" +
					replacement.getId() + "]], replaced id [[" + getId() + "]].");
		}
		if (parent == null)
		{
			throw new IllegalStateException(
				"This method can only be called on a component that has already been added to its parent.");
		}
		parent.replace(replacement);
		return replacement;
	}

	/**
	 * @param component
	 *            The component to compare with
	 * @return True if the given component's model is the same as this component's model.
	 */
	public final boolean sameInnermostModel(final Component component)

View on GitHub (pinned to d44925c47c)

Solutions

  1. Ensure the replacement uses exactly the original component's id: `new Label(old.getId(), model)`.
  2. Capture the id from the existing component rather than hardcoding.
  3. If ids must differ, remove the old component and add the new one via the parent instead.
  4. Add a unit/test check comparing getId() before calling replaceWith.
  5. Search markup and Java for mismatched wicket:id strings.

Example fix

// before
label.replaceWith(new MultiLineLabel("otherId", model));
// after
label.replaceWith(new MultiLineLabel(label.getId(), model));
Defensive patterns

Strategy: validation

Validate before calling

if (!replacement.getId().equals(existing.getId())) { replacement = rebuildWithId(existing.getId()); }

Type guard

boolean swappable(Component old, Component newC) { return old.getId().equals(newC.getId()); }

Try / catch

try { old.replaceWith(replacement); } catch (IllegalArgumentException e) { log.error("Replacement id mismatch: " + e.getMessage()); }

Prevention

When it happens

Trigger: Creating a replacement component with a different string id than the original (e.g. new Label("foo") replacing new Label("bar")); copying code that renames ids; building replacements dynamically with generated ids.

Common situations: Refactoring that renamed one of the two components; constructing replacements in loops with index-based ids; attempting to swap a Panel for a Fragment with a different wicket:id.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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