NationalSecurityAgency/ghidra · error · IllegalArgumentException

The given prefix (%s) is not actually a prefix of this (%s).

Error message

The given prefix (%s) is not actually a prefix of this (%s).

What it means

Sequence.relativize computes the continuation from a prefix to this sequence. It requires that the argument is a true prefix — every step in the prefix must match the corresponding step in this sequence up to the prefix's length, with this sequence being strictly longer (CompareResult.REL_GT). If the argument is unrelated, shorter in the wrong way, or divergent, the exception is thrown.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/Sequence.java:365

	 * <p>
	 * The returned step sequence should not be manipulated, since it may just be this sequence.
	 * 
	 * @see #compareSeq(Sequence)
	 * @param prefix the prefix
	 * @return the relative sequence from prefix to this
	 * @throws IllegalArgumentException if prefix is not a prefix of this sequence
	 */
	public Sequence relativize(Sequence prefix) {
		if (prefix.isNop()) {
			return this;
		}
		CompareResult comp = compareSeq(prefix);
		Sequence result = new Sequence();
		if (comp == CompareResult.EQUALS) {
			return result;
		}
		if (comp != CompareResult.REL_GT) {
			throw new IllegalArgumentException(String.format(
				"The given prefix (%s) is not actually a prefix of this (%s).", prefix, this));
		}

		int lastStepIndex = prefix.steps.size() - 1;
		Step ancestorLast = prefix.steps.get(lastStepIndex);
		Step continuation = this.steps.get(lastStepIndex);
		result.advance(continuation.subtract(ancestorLast));
		result.steps.addAll(steps.subList(prefix.steps.size(), steps.size()));
		return result;
	}

	/**
	 * Compute to total number of ticks specified
	 * 
	 * @return the total
	 */
	public long totalTickCount() {
		long count = 0;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Verify the prefix is actually a prefix of this sequence using compareSeq before calling relativize: if (compareSeq(prefix) == CompareResult.REL_GT)
  2. Ensure both schedules were constructed from the same base snapshot with only appended steps differing
  3. If the schedules are unrelated, compute the difference from a common ancestor instead
  4. Use compareSeq to inspect the relationship and handle REL_LT / UNREL_* cases separately

Example fix

// before
Sequence diff = fullSchedule.relativize(baseSchedule);
// after
CompareResult rel = fullSchedule.compareSeq(baseSchedule);
if (rel == CompareResult.REL_GT) {
    Sequence diff = fullSchedule.relativize(baseSchedule);
} else {
    // re-derive from common ancestor
}
Defensive patterns

Strategy: validation

Validate before calling

CompareResult rel = fullSequence.compareSeq(prefix);
if (rel == CompareResult.REL_GT) {
    Sequence diff = fullSequence.relativize(prefix);
} else {
    // prefix is not a prefix; handle fallback
}

Type guard

// N/A — Sequence relationship is runtime, not type-level

Try / catch

try {
    Sequence diff = fullSequence.relativize(prefix);
} catch (IllegalArgumentException e) {
    // recompute from a known common ancestor
}

Prevention

When it happens

Trigger: Calling relativize(prefix) where prefix diverges from this at some step index, or where prefix is actually longer than this. The compareSeq method returns UNREL_LT, UNREL_GT, or REL_LT instead of the required REL_GT.

Common situations: Computing the schedule delta between two snapshots or emulated positions where one schedule was not derived from the other. Passing a schedule from a different thread ordering or a different stepping path. Using relativize on schedules that share a common ancestor but where the prefix has already branched.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/85b2b5d9bb34b4b3. Report an issue: GitHub.