jackwener/OpenCLI · error · ConfigError

Unknown pipeline step "${op}" at index ${i}. Check the YAML

Error message

Unknown pipeline step "${op}" at index ${i}. Check the YAML pipeline step name or register the custom step before execution.

What it means

executePipeline() resolves each YAML pipeline step's operation name to a registered handler via getStep(op). When no handler exists for the step's `op`, it throws this ConfigError telling you the step index and pointing you at either fixing the YAML step name or registering the custom step before execution. This is a configuration/registration error, not a runtime failure.

Source

Thrown at src/pipeline/executor.ts:41

  ctx: PipelineContext = {},
): Promise<unknown> {
  const args = ctx.args ?? {};
  const debug = ctx.debug ?? false;
  let data: unknown = null;
  const total = pipeline.length;

  try {
    for (let i = 0; i < pipeline.length; i++) {
      const step = pipeline[i];
      if (!step || typeof step !== 'object') continue;
      for (const [op, params] of Object.entries(step)) {
        if (debug) debugStepStart(i + 1, total, op, params);

        const handler = getStep(op);
        if (handler) {
          data = await executeStepWithRetry(handler, page, params, data, args, op, ctx.stepRetries);
        } else {
          throw new ConfigError(
            `Unknown pipeline step "${op}" at index ${i}.`,
            'Check the YAML pipeline step name or register the custom step before execution.',
          );
        }

        if (debug) debugStepResult(data);
      }
    }
  } catch (err) {
    // Attempt cleanup: release automation tab lease on pipeline failure.
    if (page?.closeWindow) {
      try { await page.closeWindow(); } catch { /* ignore */ }
    }
    throw err;
  }
  return data;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the step name at the given index against the library's documented step list and fix the typo.
  2. Register the custom step (call the registration API for your handler) before invoking executePipeline.
  3. Verify plugin imports/initialization actually run before pipeline execution.
  4. Check release notes for renamed steps after upgrading.

Example fix

// before
steps:
  - op: screeenshot
// after
steps:
  - op: screenshot
// or, for custom steps:
registerStep('screeenshot', myHandler); // before executePipeline(...)
Defensive patterns

Strategy: validation

Validate before calling

// Validate all pipeline step names before executing
function validatePipelineSteps(pipeline, knownSteps) {
  const unknown = [];
  pipeline.steps.forEach((s, i) => {
    if (!knownSteps.has(s.op)) unknown.push(`index ${i}: "${s.op}"`);
  });
  if (unknown.length) throw new Error(`Unknown pipeline steps -> ${unknown.join(', ')}`);
}
// validatePipelineSteps(yamlPipeline, new Set(await listRegisteredSteps()));

Try / catch

try {
  await executePipeline(pipeline, page, args);
} catch (e) {
  if (e instanceof ConfigError && /Unknown pipeline step/.test(e.message)) {
    const op = e.message.match(/Unknown pipeline step "([^"]+)"/)?.[1];
    logger.error(`Unregistered step "${op}" — check YAML spelling or registerStep("${op}", handler)`);
    process.exitCode = 2;
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: A YAML pipeline containing a step whose `op` is misspelled (e.g. `clicp: screenshot` instead of `click`) or references a plugin/custom step that was never registered via the step registry before executePipeline (called from runCommand) runs.

Common situations: Typo or casing mismatch in pipeline YAML, using a step from a plugin whose registration code was removed or not imported, version upgrade renaming steps, or copy-pasting a pipeline between projects with different registered steps.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/4c83ec468a6927ac. Report an issue: GitHub.