AWS Lambda Durable Functions
awslabs/agent-plugins
Build resilient, long-running, multi-step applications with AWS Lambda durable functions with automatic state persistence, retry logic, and orchestration for long-running executions.
A skill your agent uses when designing error hierarchies, propagating errors across service boundaries, implementing retry and backoff logic, writing structured error responses for APIs, or making…
$ npx skills add kid-sid/claude-spellbook --skill error-handling -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install kid-sid/claude-spellbook error-handling --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/error-handling .claude/skills/error-handling && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "error-handling" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handling into .claude/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handlingType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add kid-sid/claude-spellbook --skill error-handling -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install kid-sid/claude-spellbook error-handling --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/error-handling .agents/skills/error-handling && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "error-handling" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handling into .agents/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kid-sid/claude-spellbook --skill error-handling -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install kid-sid/claude-spellbook error-handling --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/error-handling .cursor/skills/error-handling && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "error-handling" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handling into .cursor/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/kid-sid/claude-spellbook.git --path skills/error-handling--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add kid-sid/claude-spellbook --skill error-handling -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install kid-sid/claude-spellbook error-handling --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/error-handling .gemini/skills/error-handling && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "error-handling" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handling into .gemini/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install kid-sid/claude-spellbook error-handlingInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add kid-sid/claude-spellbook --skill error-handling -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/error-handling .github/skills/error-handling && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "error-handling" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handling into .github/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kid-sid/claude-spellbook --skill error-handling -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install kid-sid/claude-spellbook error-handling --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/error-handling .opencode/skills/error-handling && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "error-handling" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/error-handling into .opencode/skills/error-handling/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
error-handlingA skill your agent uses when designing error hierarchies, propagating errors across service boundaries, implementing retry and backoff logic, writing structured error responses for APIs, or making…
Error Handling is an agent skill from kid-sid/claude-spellbook. Use when designing error hierarchies, propagating errors across service boundaries, implementing retry and backoff logic, writing structured error responses for APIs, or making error handling consistent across a Python, TypeScript, or Go codebase.
Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Error handling and Microservices. It works with Python and TypeScript. The repository describes itself as: A curated collection of skills, prompts, and workflows that extend Claude's capabilities — your personal grimoire for AI-powered development. The licence is MIT.
Read from SKILL.md and the folder at commit a7c2ac9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python, typescript, go and json).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Error Handling loads about 3k tokens when it runs. Until then it costs about 66 tokens; SKILL.md has 541 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from kid-sid/claude-spellbook at commit a7c2ac9, republished under its MIT licence (© kid-sid). 541 words, ~2,969 tokens.
.claude/skills/error-handling/SKILL.md (or your agent's skills folder).Patterns for structured errors, propagation, retries, and consistent failure surfaces across Python, TypeScript, and Go.
except blocksClassify errors before deciding how to handle them — the right response depends on what kind of failure occurred.
| Class | Examples | Handle by |
|---|---|---|
| Validation | Missing field, bad format | Return 400 immediately — no retry |
| Not found | Unknown ID, deleted resource | Return 404 — no retry |
| Auth | Invalid token, expired session | Return 401/403 — no retry |
| Transient | Network timeout, DB connection blip | Retry with backoff |
| Dependency | Third-party API down, queue unavailable | Retry, then circuit-break |
| Logic bug | Null deref, assertion failure | Log + alert — do not retry or swallow |
| Rate limited | 429 from upstream | Retry after Retry-After header |
# Base domain error — all app errors inherit from this
class AppError(Exception):
def __init__(self, message: str, code: str, status: int = 500) -> None:
super().__init__(message)
self.code = code
self.status = status
class NotFoundError(AppError):
def __init__(self, resource: str, id: str) -> None:
super().__init__(f"{resource} '{id}' not found", "NOT_FOUND", 404)
class ValidationError(AppError):
def __init__(self, field: str, reason: str) -> None:
super().__init__(f"Invalid '{field}': {reason}", "VALIDATION_ERROR", 400)
class TransientError(AppError):
"""Signals a retry is safe."""
def __init__(self, message: str) -> None:
super().__init__(message, "TRANSIENT_ERROR", 503)// Tagged union — exhaustive handling without instanceof chains
type AppError =
| { tag: "NOT_FOUND"; resource: string; id: string }
| { tag: "VALIDATION"; field: string; reason: string }
| { tag: "UNAUTHORIZED" }
| { tag: "TRANSIENT"; message: string; retryable: true };
function notFound(resource: string, id: string): AppError {
return { tag: "NOT_FOUND", resource, id };
}
// Result type — explicit error path, no throw/catch in business logic
type Result<T, E = AppError> = { ok: true; value: T } | { ok: false; error: E };
function ok<T>(value: T): Result<T> { return { ok: true, value }; }
function err<E>(error: E): Result<never, E> { return { ok: false, error }; }
// Usage
async function getUser(id: string): Promise<Result<User>> {
const user = await db.findUser(id);
if (!user) return err(notFound("User", id));
return ok(user);
}
const result = await getUser("123");
if (!result.ok) {
// result.error is fully typed here
switch (result.error.tag) {
case "NOT_FOUND": return res.status(404).json({ error: result.error });
case "UNAUTHORIZED": return res.status(401).json({ error: "Unauthorized" });
}
}// Sentinel errors for classification
var (
ErrNotFound = errors.New("not found")
ErrValidation = errors.New("validation error")
ErrTransient = errors.New("transient error")
)
// Structured error with context
type AppError struct {
Code string
Message string
Err error // wrapped cause
}
func (e *AppError) Error() string { return e.Message }
func (e *AppError) Unwrap() error { return e.Err }
func NotFound(resource, id string) *AppError {
return &AppError{
Code: "NOT_FOUND",
Message: fmt.Sprintf("%s '%s' not found", resource, id),
Err: ErrNotFound,
}
}
// Propagate with context — never discard the original error
func getUser(ctx context.Context, id string) (*User, error) {
user, err := db.FindUser(ctx, id)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, NotFound("User", id)
}
return nil, fmt.Errorf("getUser %s: %w", id, err)
}
return user, nil
}
// Check error class at the boundary
if errors.Is(err, ErrNotFound) {
http.Error(w, "Not found", http.StatusNotFound)
return
}
if errors.Is(err, ErrTransient) {
http.Error(w, "Service unavailable", http.StatusServiceUnavailable)
return
}# Python — chain exceptions
try:
result = db.query(sql)
except psycopg2.OperationalError as exc:
raise TransientError("database unavailable") from exc # preserves __cause__
# BAD — swallows the original traceback
raise TransientError("database unavailable")// TypeScript — wrap with cause
throw new Error("Database unavailable", { cause: originalError });
// BAD — loses original stack
throw new Error("Database unavailable");// Go — %w verb wraps for errors.Is / errors.As
return fmt.Errorf("fetchOrders: %w", err) // ✓ preserves chain
// BAD — breaks unwrapping
return fmt.Errorf("fetchOrders: %v", err) // ✗ wraps as string only
return errors.New("fetchOrders failed") // ✗ discards originalJitter prevents thundering herd when many callers retry simultaneously.
# Python
import asyncio, random
async def with_retry(fn, *, max_attempts: int = 3, base_delay: float = 0.5):
for attempt in range(max_attempts):
try:
return await fn()
except TransientError:
if attempt == max_attempts - 1:
raise
delay = base_delay * (2 ** attempt) + random.uniform(0, 0.3)
await asyncio.sleep(delay)// TypeScript
async function withRetry<T>(
fn: () => Promise<T>,
{ maxAttempts = 3, baseDelay = 500 } = {}
): Promise<T> {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
if (!isRetryable(err) || attempt === maxAttempts - 1) throw err;
const delay = baseDelay * 2 ** attempt + Math.random() * 300;
await new Promise((r) => setTimeout(r, delay));
}
}
throw new Error("unreachable");
}
function isRetryable(err: unknown): boolean {
return err instanceof AppError && err.tag === "TRANSIENT";
}// Go
func WithRetry(ctx context.Context, fn func() error, maxAttempts int) error {
var err error
for attempt := range maxAttempts {
if err = fn(); err == nil {
return nil
}
if !errors.Is(err, ErrTransient) {
return err
}
if attempt == maxAttempts-1 {
break
}
delay := time.Duration(math.Pow(2, float64(attempt))*500)*time.Millisecond +
time.Duration(rand.Intn(300))*time.Millisecond
select {
case <-time.After(delay):
case <-ctx.Done():
return ctx.Err()
}
}
return fmt.Errorf("after %d attempts: %w", maxAttempts, err)
}Every API error should include: machine-readable code, human-readable message, optional details for field-level problems.
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "field": "email", "reason": "must be a valid email address" },
{ "field": "age", "reason": "must be a positive integer" }
],
"request_id": "req_01HX..."
}
}# FastAPI global handler
from fastapi import Request
from fastapi.responses import JSONResponse
@app.exception_handler(AppError)
async def app_error_handler(request: Request, exc: AppError) -> JSONResponse:
return JSONResponse(
status_code=exc.status,
content={
"error": {
"code": exc.code,
"message": str(exc),
"request_id": request.state.request_id,
}
},
)// Express global error handler — must be last middleware
app.use((err: unknown, req: Request, res: Response, _next: NextFunction) => {
const requestId = req.headers["x-request-id"] ?? crypto.randomUUID();
if (err instanceof AppError) {
return res.status(err.status).json({
error: { code: err.code, message: err.message, request_id: requestId },
});
}
console.error("Unhandled error", err);
res.status(500).json({
error: { code: "INTERNAL_ERROR", message: "An unexpected error occurred", request_id: requestId },
});
});| Severity | When | Fields to include |
|---|---|---|
ERROR | Unhandled or unexpected failures | message, stack, request_id, user_id |
WARN | Handled but notable (retry succeeded, degraded mode) | message, attempt count |
INFO | Expected failures returned to caller (404, 400) | code, path — no stack trace |
DEBUG | Retry attempts, circuit state | attempt, delay, error message |
# BAD — log and re-raise doubles the noise
except SomeError as exc:
logger.error("Failed", exc_info=True)
raise # logged again by the global handler
# GOOD — log once at the boundary, propagate elsewhere
except SomeError as exc:
raise TransientError("upstream failed") from exc # logged once at the topexcept / catch (e) {} — swallows the error entirely; always re-raise or handle explicitly.raise Exception("something went wrong") — generic base types give callers no way to branch; use typed domain errors.%v instead of %w in Go — breaks errors.Is / errors.As unwrapping; always use %w when wrapping.err in Go — _ = fn() silently discards failures; use //nolint:errcheck only with a documented reason.request_id in error responses — makes support and debugging impossible; always include a correlation ID.code, message, and HTTP status — no raw Exception("string") at boundariesfrom exc / { cause } / %w) — original cause preservedTRANSIENT errors retried, never validation or auth errorscode, message, and request_id — consistent shape across all endpointsINFO used for expected 4xx, ERROR for unexpected 5xx — no stack traces in 404 logserror return values without a documented reason© kid-sid, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/error-handling of kid-sid/claude-spellbook.
Open the folder on GitHubat commit a7c2ac9
Error Handling next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Error Handling this skillkid-sid/claude-spellbook | 189 | — | ~3k | Automated safety check: Pass | MIT | |
| AWS Lambda Durable Functionsawslabs/agent-plugins | 912 | — | ~2.3k | Automated safety check: Pass | Apache-2.0 | |
| Nodejsblencorp/claude-code-kit | 106 | — | ~2.6k | Automated safety check: Pass | MIT | |
| Node Backend Development Guidelinesdiet103/claude-code-infrastructure-showcase | 10k | 2 repos | ~2k | Automated safety check: Pass | MIT | |
| AWS Serverless Edazxkane/aws-skills | 367 | 4 repos | ~3.2k | Automated safety check: Pass | MIT | |
| Temporal Developerlatitude-dev/latitude-llm | 4.7k | — | ~1.5k | Automated safety check: Pass | MIT |
awslabs/agent-plugins
Build resilient, long-running, multi-step applications with AWS Lambda durable functions with automatic state persistence, retry logic, and orchestration for long-running executions.
blencorp/claude-code-kit
Core Node.js backend patterns for TypeScript applications including async/await error handling, middleware concepts, configuration management, testing strategies, and layered architecture principles.
diet103/claude-code-infrastructure-showcase
Sets layered architecture and coding rules for Node.js, Express and TypeScript microservices, covering routes, controllers, services, repositories, Prisma, Sentry and Zod.
zxkane/aws-skills
AWS serverless and event-driven architecture expert based on Well-Architected Framework.
latitude-dev/latitude-llm
This skill should be used when the user asks to "create a Temporal workflow", "write a Temporal activity", "debug stuck workflow", "fix non-determinism error", "Temporal Python", "Temporal…
xiaods/k8e
Run a goal end to end inside an isolated K8E sandbox pod (gVisor / Kata / Firecracker) instead of on the host: exec bash / Python / Node / TypeScript, install packages, move files in and out, reuse…
kid-sid/claude-spellbook
A skill your agent uses when building or reviewing UI components for keyboard and screen reader compatibility, adding ARIA to custom widgets, auditing a page for WCAG AA conformance, or preparing…
kid-sid/claude-spellbook
A skill your agent uses when building, wiring, or debugging an Agentex agent — choosing agent type, configuring acp.py and manifest.yaml, using adk.messages or adk.state, or resolving…
kid-sid/claude-spellbook
A skill your agent uses when building production LLM applications — designing RAG pipelines, choosing vector databases, implementing agent orchestration, optimizing cost, or adding AI safety…
kid-sid/claude-spellbook
A skill your agent uses when building or refactoring Angular applications — choosing between signals, RxJS, and NgRx for state, configuring routing with guards and lazy loading, optimizing change…
kid-sid/claude-spellbook
A skill your agent uses when designing new REST endpoints, reviewing an existing API contract, adding pagination or filtering, planning a versioning strategy, or building a public or partner-facing…
kid-sid/claude-spellbook
A skill your agent uses when implementing login flows, issuing or validating JWTs, setting up OAuth2/OIDC with a provider, designing role-based or attribute-based access control, securing API…
Works with
Categories
A skill your agent uses when designing error hierarchies, propagating errors across service boundaries, implementing retry and backoff logic, writing structured error responses for APIs, or making…. Error Handling is an agent skill from kid-sid/claude-spellbook. Use when designing error hierarchies, propagating errors across service boundaries, implementing retry and backoff logic, writing structured error responses for APIs, or making error handling consistent across a Python, TypeScript, or Go codebase.
Error Handling fits situations like: designing error hierarchies; propagating errors across service boundaries; implementing retry and backoff logic; writing structured error responses for APIs.
Run `npx skills add kid-sid/claude-spellbook --skill error-handling -a claude-code`. Or copy the skill folder (skills/error-handling in kid-sid/claude-spellbook) into .claude/skills/error-handling in your project. Claude Code loads it when a task matches its description.
Run `npx skills add kid-sid/claude-spellbook --skill error-handling -a codex`. Or copy the skill folder (skills/error-handling in kid-sid/claude-spellbook) into .agents/skills/error-handling in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kid-sid/claude-spellbook --skill error-handling -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/error-handling, .gemini/skills/error-handling, .github/skills/error-handling and .opencode/skills/error-handling in your project.
SKILL.md names no scripts, command-line tools or credentials: Error Handling is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Error Handling is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Error Handling: AWS Lambda Durable Functions (awslabs/agent-plugins, 912 stars), Nodejs (blencorp/claude-code-kit, 106 stars), Node Backend Development Guidelines (diet103/claude-code-infrastructure-showcase, 10k stars) and AWS Serverless Eda (zxkane/aws-skills, 367 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
kid-sid (a GitHub user) maintains it in kid-sid/claude-spellbook, which has 189 GitHub stars. The repository holds 54 skills in this directory. The repository was last updated on August 5, 2026.
Source: kid-sid/claude-spellbook on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.