mastra-ai/mastra · error · StepExecutionError

StepExecutionError(res.status, text)

Error message

StepExecutionError(res.status, text)

What it means

The HTTP remote worker strategy executes a step by POSTing to a remote endpoint; when the response is not ok it reads the body text and throws StepExecutionError carrying the HTTP status and body. This surfaces remote execution failures (auth, 404, 500, validation) to the worker caller.

Source

Thrown at packages/core/src/worker/strategies/http-remote-strategy.ts:79

    );

    const body = this.#buildBody(params);

    const signal = this.#combineSignals(params.abortSignal);

    const res = await fetch(url, {
      method: 'POST',
      headers: {
        'content-type': 'application/json',
        ...this.#buildAuthHeaders(),
      },
      body,
      signal,
    });

    if (!res.ok) {
      const text = await res.text();
      throw new StepExecutionError(res.status, text);
    }

    return res.json() as Promise<StepResult<unknown, unknown, unknown, unknown>>;
  }

  /**
   * Build a JSON-serializable request body. The `params.requestContext` is
   * a plain object; if a caller stuffed a non-serializable value into it we
   * surface a clear error instead of silently dropping fields.
   *
   * `abortSignal` is consumed via fetch's `signal` argument — it must not
   * be in the body.
   */
  #buildBody(params: StepExecutionParams): string {
    const { abortSignal: _abortSignal, requestContext, ...rest } = params;
    let safeRequestContext: Record<string, unknown>;
    try {
      safeRequestContext = JSON.parse(JSON.stringify(requestContext ?? {}));

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Read the status and body in StepExecutionError to identify the remote failure and fix the remote handler
  2. Verify the endpoint URL, method, and auth headers used by the strategy config
  3. Check the remote service logs for the corresponding request's stack trace
  4. Add retry with backoff only for transient statuses (502/503/504)

Example fix

// before
throw new StepExecutionError(res.status, text);
// after (caller side)
try {
  result = await strategy.executeStep(params);
} catch (e) {
  if (e instanceof StepExecutionError && e.status >= 500) return retry(params);
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const url = new URL(endpoint);
if (url.protocol !== 'https:' && url.protocol !== 'http:') throw new Error('bad endpoint');

Type guard

function isStepExecutionError(e: unknown): e is StepExecutionError {
  return e instanceof StepExecutionError;
}

Try / catch

try {
  result = await strategy.executeStep(params);
} catch (e) {
  if (e instanceof StepExecutionError) {
    if (e.status === 503 || e.status === 502) return retryWithBackoff(params);
    console.error(`Remote step failed: ${e.status} ${e.body}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Remote step endpoint returns 401/403 (bad auth token), 404 (wrong URL/path), 500 (handler crashed), or 400 (payload rejected by the remote service).

Common situations: Expired service-to-service credentials; deployed worker pointing at an outdated or wrong-namespace remote URL; remote handler throwing due to a bug or incompatible step schema after a version upgrade.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/bbece435eb871773. Report an issue: GitHub.