Skip to content

skills/workflow/SKILL.md: the 429 RetryableError branch is unreachable (429 is caught by the preceding 400-499 FatalError) #3652

Description

@fewfindher

Where

skills/workflow/SKILL.md (version 1.10), the Error Handling section, lines 285-291 on main:

if (res.status >= 400 && res.status < 500) {
  throw new FatalError(`Client error: ${res.status}`);
}
if (res.status === 429) {
  throw new RetryableError("Rate limited", { retryAfter: "5m" });
}

The problem

429 satisfies res.status >= 400 && res.status < 500, so the first branch always throws first. The RetryableError branch is unreachable, and the example teaches the exact opposite of what it intends: a rate-limited request terminates the workflow permanently instead of retrying after the stated delay.

This is the section of the skill that explains when to reach for RetryableError rather than FatalError, and the code beneath it demonstrates a case where RetryableError can never fire.

Why it is worth fixing

This file ships as an agent skill, so the example is copied into generated code close to verbatim. A rate limit is one of the most common transient failures a workflow step will hit, and this shape turns every one of them into a permanent failure. The prose is right; only the ordering is wrong.

Suggested fix

Check the retryable case first:

if (res.status === 429) {
  throw new RetryableError("Rate limited", { retryAfter: "5m" });
}
if (res.status >= 400 && res.status < 500) {
  throw new FatalError(`Client error: ${res.status}`);
}

The same two branches also appear in the right order nowhere else in the file, so this is the only place the pattern is shown.

Happy to open a PR if that is easier.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions