Stirling-Tools/Stirling-PDF · error · Error

${operationName} operation failed: ${error.response?.data ||

Error message

${operationName} operation failed: ${error.response?.data || error.message}

What it means

A catch-all wrapper thrown by executeToolOperationWithPrefix when any error escapes the tool execution body (single-file, multi-file, or customProcessor path). It re-throws with the operationName prefixed and the underlying cause attached via { cause: error }, preferring error.response?.data (Axios-style backend error body) over error.message. This is the error a caller of the executor actually sees for any backend or processing failure.

Source

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

    // Execute based on tool type
    if (config.toolType === ToolType.multiFile) {
      return await executeMultiFileOperation(
        config,
        mergedParameters,
        files,
        filePrefix,
      );
    } else {
      return await executeSingleFileOperation(
        config,
        mergedParameters,
        files,
        filePrefix,
      );
    }
  } catch (error: any) {
    console.error(`❌ ${operationName} failed:`, error);
    throw new Error(
      `${operationName} operation failed: ${error.response?.data || error.message}`,
      {
        cause: error,
      },
    );
  }
};

/**
 * 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,

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Inspect error.cause for the original error object; the wrapper preserves it.
  2. If error.response.data is present, read the backend's message — it usually pinpoints the bad parameter or file.
  3. Check browser DevTools Network tab for the failing POST to see status code and response body.
  4. If it is a transient network/timeout issue, consider retrying with backoff for idempotent operations.
  5. Validate file types and parameters against the tool's requirements before submitting.

Example fix

// before — caller does not inspect cause
catch (e) { show(e.message); }
// after — unwrap the real error
catch (e) {
  const detail = e.cause?.response?.data ?? e.cause?.message ?? e.message;
  show(`${operationName} failed: ${detail}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: ensure files are non-empty and of expected type before submitting.
function validateToolInputs(op: string, params: any, files: File[]): string | null {
  if (!files.length) return 'No files provided.';
  if (files.some(f => f.size === 0)) return 'One or more files are empty.';
  return null;
}
const issue = validateToolInputs(op, params, files);
if (issue) { showUser(issue); return; }

Type guard

function isAxiosError(e: unknown): e is { response?: { status: number; data: any }; message: string } {
  return !!e && typeof e === 'object' && 'response' in e;
}

Try / catch

try {
  await executeToolOperation(op, params, files, registry);
} catch (e) {
  const err = e as Error & { cause?: any };
  const cause = err.cause;
  const detail = cause?.response?.data ?? cause?.message ?? err.message;
  const status = cause?.response?.status;
  if (status === 401 || status === 403) showUser('Session expired. Please log in again.');
  else if (status && status >= 500) showUser('Server error. Please try again later.');
  else showUser(`${op} failed: ${detail}`);
}

Prevention

When it happens

Trigger: The backend POST returns a non-2xx (Axios rejects, error.response.data holds the server message). A network failure or timeout occurs (no response object, message is the network error). A customProcessor throws synchronously or its internal processing rejects. The processMultiFileResponse/zip extraction step fails downstream.

Common situations: Backend is down or the endpoint returned 400/500 (e.g. malformed params, unsupported file type, server exception). The user's session expired and the API returned 401/403. A large file caused a gateway timeout. The backend PDF operation threw because the input file was corrupt or password-protected.

Related errors


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