Stirling-Tools/Stirling-PDF · error · Error

No operations in automation

Error message

No operations in automation

What it means

Thrown by executeAutomationSequence when automation.operations is missing or is an empty array. The executor iterates over operations to run each step; with zero steps there is nothing to execute, so it fails fast rather than silently returning the input files. This guards against a degenerate or incompletely-built automation being run.

Source

Thrown at frontend/editor/src/core/utils/automationExecutor.ts:231

  }
};

/**
 * Execute an entire automation sequence
 */
export const executeAutomationSequence = async (
  automation: any,
  initialFiles: File[],
  toolRegistry: ToolRegistry,
  onStepStart?: (stepIndex: number, operationName: string) => void,
  onStepComplete?: (stepIndex: number, resultFiles: File[]) => void,
  onStepError?: (stepIndex: number, error: string) => void,
): Promise<File[]> => {
  console.log(`🚀 Starting automation: ${automation.name || "Unnamed"}`);
  console.log(`📁 Input: ${initialFiles.length} file(s)`);

  if (!automation?.operations || automation.operations.length === 0) {
    throw new Error("No operations in automation");
  }

  let currentFiles = [...initialFiles];
  const automationPrefix = automation.name
    ? `${automation.name}_`
    : "automated_";

  for (let i = 0; i < automation.operations.length; i++) {
    const operation = automation.operations[i];

    console.log(
      `\n📋 Step ${i + 1}/${automation.operations.length}: ${operation.operation}`,
    );
    console.log(`   Input: ${currentFiles.length} file(s)`);

    try {
      onStepStart?.(i, operation.operation);

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Ensure at least one operation is added to the automation before calling executeAutomationSequence.
  2. Add a UI guard (disabled Run button) when automation.operations.length === 0.
  3. Validate the automation object shape (has operations array with length > 0) before passing it to the executor.
  4. If loading from storage, verify the operations field survived serialization.

Example fix

// before
executeAutomationSequence({ name: 'x', operations: [] }, files, reg);
// after
if (!automation.operations?.length) { warn('Add at least one step'); return; }
executeAutomationSequence(automation, files, reg);
Defensive patterns

Strategy: validation

Validate before calling

function hasOperations(automation: any): automation is { operations: unknown[] } {
  return !!automation && Array.isArray(automation.operations) && automation.operations.length > 0;
}

if (!hasOperations(automation)) {
  throw new Error('Cannot run an automation with no steps.');
}

Type guard

function isRunnableAutomation(a: unknown): a is { operations: Array<{ operation: string }> } {
  return !!a && typeof a === 'object' &&
    Array.isArray((a as any).operations) &&
    (a as any).operations.length > 0 &&
    (a as any).operations.every((o: any) => typeof o?.operation === 'string');
}

Try / catch

try {
  await executeAutomationSequence(automation, files, registry);
} catch (e) {
  if (e instanceof Error && e.message === 'No operations in automation') {
    showUser('Add at least one operation before running.');
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling executeAutomationSequence(automation, files, registry, ...) where automation.operations is undefined, null, or [] — e.g. a newly-created automation with no steps added, a deserialized automation that lost its operations field, or an automation object constructed inline without steps.

Common situations: User clicks 'Run' on a freshly-created automation before adding any operations. An automation was imported/loaded but the operations array was stripped or nested under a different key. The automation builder allowed saving an empty sequence.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/a2ffd6956fbd71ee. Report an issue: GitHub.