NationalSecurityAgency/ghidra · error · IllegalArgumentException

Cannot parse skip step: '

Error message

Cannot parse skip step: '

What it means

SkipStep.parse expects a step specification beginning with 's' (for 'skip'). This is the structural check — if the spec does not start with 's', it cannot be a skip step. The skip step skips a number of p-code/instruction ticks without emulation on a thread. This is the first guard in the parser before attempting to decode the numeric portion.

Source

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

 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ghidra.trace.model.time.schedule;

import ghidra.pcode.emu.PcodeThread;
import ghidra.trace.model.time.schedule.TraceSchedule.TimeRadix;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;

public class SkipStep extends AbstractStep {

	public static SkipStep parse(long threadKey, String stepSpec, TimeRadix radix) {
		if (!stepSpec.startsWith("s")) {
			throw new IllegalArgumentException("Cannot parse skip step: '" + stepSpec + "'");
		}
		try {
			return new SkipStep(threadKey, radix.decode(stepSpec.substring(1)));
		}
		catch (NumberFormatException e) {
			throw new IllegalArgumentException("Cannot parse skip step: '" + stepSpec + "'");
		}
	}

	/**
	 * Construct a skip step for the given thread with the given tick count
	 * 
	 * @param threadKey the key of the thread in the trace, -1 for the "last thread"
	 * @param tickCount the number of ticks to skip on the thread
	 */
	public SkipStep(long threadKey, long tickCount) {
		super(threadKey, tickCount);
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Prefix the count with 's', e.g. 's5' instead of '5'
  2. Use Step.parse as the entry point instead of SkipStep.parse directly — it dispatches based on the prefix
  3. If you have a numeric count, construct the step directly: new SkipStep(threadKey, tickCount)

Example fix

// before
SkipStep.parse(1, "5", radix);
// after
SkipStep.parse(1, "s5", radix);
// or construct directly
new SkipStep(1, 5);
Defensive patterns

Strategy: validation

Validate before calling

boolean isSkipStepSpec(String stepSpec) {
    return stepSpec != null && stepSpec.startsWith("s");
}

Type guard

// N/A

Try / catch

try {
    SkipStep step = SkipStep.parse(threadKey, stepSpec, radix);
} catch (IllegalArgumentException e) {
    // not a skip step; try tick or patch parsing
}

Prevention

When it happens

Trigger: Step.parse routes to SkipStep.parse when stepSpec.startsWith("s") is true, so this specific branch (line 27) is only hit when called directly or when routing logic changes. The more common path is that Step.parse dispatches correctly. A direct call with a spec like '5' or '{r0=1}' triggers this.

Common situations: Calling SkipStep.parse directly instead of through Step.parse. Passing a raw numeric spec that was expected to be a skip but lacks the 's' prefix. Misunderstanding the DSL syntax where 's5' means skip 5 ticks but '5' means tick step.

Related errors


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