theonedev/onedev · error · org.apache.wicket.WicketRuntimeException

The component ID must not contain ':' or '~' chars.

Error message

The component ID must not contain ':' or '~' chars.

What it means

setId() also rejects ids containing ':' or '~' because those characters have special meaning in Wicket component paths (':' separates path segments, '~' is used in AJAX/versioned paths) and would break path resolution.

Source

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

	/**
	 * Sets the id of this component.
	 * 
	 * @param id
	 *            The non-null id of this component
	 */
	final Component setId(final String id)
	{
		if (!(this instanceof Page))
		{
			if (Strings.isEmpty(id))
			{
				throw new WicketRuntimeException("Null or empty component ID's are not allowed.");
			}
		}

		if ((id != null) && (id.indexOf(':') != -1 || id.indexOf('~') != -1))
		{
			throw new WicketRuntimeException("The component ID must not contain ':' or '~' chars.");
		}

		this.id = id;
		return this;
	}

	/**
	 * THIS IS A WICKET INTERNAL API. DO NOT USE IT.
	 * 
	 * Sets the parent of a component. Typically what you really want is parent.add(child).
	 * <p/>
	 * Note that calling setParent() and not parent.add() will connect the child to the parent, but
	 * the parent will not know the child. This might not be a problem in some cases, but e.g.
	 * child.onDetach() will not be invoked (since the parent doesn't know it is his child).
	 * 
	 * @param parent
	 *            The parent container
	 */

View on GitHub (pinned to d44925c47c)

Solutions

  1. Sanitize the id: strip/replace ':' and '~' characters before constructing the component.
  2. Use a safe derived key (e.g. hash or index) instead of raw external identifiers as ids.
  3. Do not encode hierarchy in ids; nest components in containers so Wicket builds the path.

Example fix

// before
Label l = new Label("row:" + index, model);
// after
String safeId = "row-" + index; // no ':' or '~'
Label l = new Label(safeId, model);
Defensive patterns

Strategy: validation

Validate before calling

if (id.indexOf(':') != -1 || id.indexOf('~') != -1) { id = id.replaceAll("[:~]", "-"); }

Type guard

boolean safeId = id != null && id.matches("[A-Za-z0-9_-]+");

Try / catch

try { new Label(id, model); } catch (WicketRuntimeException e) { new Label(id.replaceAll("[:~]", "_"), model); }

Prevention

When it happens

Trigger: Constructing a component with an id like "form:field", "a~b", or an id built by concatenating user/data values that contain these characters.

Common situations: Developers trying to encode hierarchy directly into an id (paths are computed by Wicket itself); ids taken from external identifiers containing colons (URIs, timestamps like 12:30); localization keys pasted as component ids.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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