NationalSecurityAgency/ghidra · error · IllegalArgumentException
Cannot parse step: '
Error message
Cannot parse step: '
What it means
PatchStep.parse rejects a step specification that is not brace-enclosed Sleigh code. The parser requires the spec to start with '{' and end with '}', stripping those delimiters to obtain the raw Sleigh statement. If either delimiter is missing, the input is not a valid patch step and the exception is thrown. This is the patch sub-parser of the schedule stepping DSL — it patches emulator machine state at a point in time.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/PatchStep.java:196
register = register.getBaseRegister();
}
int length = register.getNumBytes();
array.getData(register.getOffset(), data, 0, length);
BigInteger value = Utils.bytesToBigInteger(data, length, language.isBigEndian(), false);
if (register.isProgramCounter()) {
result.add(String.format("goto 0x%s", value.toString(16)));
}
else {
result.add(String.format("%s=0x%s", register, value.toString(16)));
}
remains.remove(spanOfRegister(register));
}
}
public static PatchStep parse(long threadKey, String stepSpec) {
// Would be nice to parse and validate the sleigh here, but need a language.
if (!stepSpec.startsWith("{") || !stepSpec.endsWith("}")) {
throw new IllegalArgumentException("Cannot parse step: '" + stepSpec + "'");
}
return new PatchStep(threadKey, stepSpec.substring(1, stepSpec.length() - 1));
}
public PatchStep(long threadKey, String sleigh) {
this.threadKey = threadKey;
this.sleigh = Objects.requireNonNull(sleigh);
this.hashCode = Objects.hash(threadKey, sleigh);
}
private void setSleigh(String sleigh) {
this.sleigh = sleigh;
this.hashCode = Objects.hash(threadKey, sleigh);
}
@Override
public int hashCode() {
return hashCode;View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure the stepSpec is wrapped in curly braces, e.g. '{r0=0x1234}'
- If building the spec dynamically, wrap with braces: '{' + sleighCode + '}'
- Use TraceSchedule.snap() or TraceSchedule.parse() with the full well-formed schedule string instead of constructing PatchStep directly
- Validate the spec with stepSpec.startsWith("{") && stepSpec.endsWith("}") before calling parse
Example fix
// before
PatchStep.parse(1, "r0=0x1234");
// after
PatchStep.parse(1, "{r0=0x1234}"); Defensive patterns
Strategy: validation
Validate before calling
boolean isValidPatchSpec(String stepSpec) {
return stepSpec != null
&& stepSpec.startsWith("{")
&& stepSpec.endsWith("}")
&& stepSpec.length() >= 2;
} Type guard
// N/A — string validation, not type narrowing
Try / catch
try {
PatchStep step = PatchStep.parse(threadKey, stepSpec);
} catch (IllegalArgumentException e) {
// log and prompt user for corrected Sleigh spec
} Prevention
- Always wrap Sleigh code in braces when building patch specs
- Use Step.parse as the entry point — it routes to PatchStep only when '{' is detected
- When building specs programmatically, use a helper that enforces braces
When it happens
Trigger: Calling PatchStep.parse(threadKey, stepSpec) or TraceSchedule.parse with a schedule whose step component contains a '{' prefix but no matching '}', or vice versa, or a completely un-braced string that gets routed to the patch branch. Also triggered indirectly via Step.parse when stepSpec starts with '{' but lacks the closing brace.
Common situations: Manually building a schedule string like '0:t1-{r0=0x1234' (missing closing brace), or programmatically concatenating Sleigh fragments without ensuring the braces are present. Copy-paste errors when constructing trace schedule specs from examples.
Related errors
- Cannot parse skip step: '
- Cannot parse step: '
- Current trace does not use Sleigh
- Could not find a register for
- Cannot rewind a negative number
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/b5f4dfee1ffc69e0.
Report an issue: GitHub.