output-build-workflow
Implement an Output SDK workflow from a plan document. Use when the user asks to build, implement, or code a workflow from an…
Handle errors caught in Output workflows without losing failure context. Use when adding workflow try/catch logic, fallbacks, partial-failure handling, custom Error classes, or typed checks for errors thrown by steps and evaluators.
Claude Code
$ npx -y skills add growthxai/output --skill output-error-try-catch --agent claude-code
Codex
$ npx skills add growthxai/output --skill output-error-try-catch -a codex -y
Cursor
$ npx skills add growthxai/output --skill output-error-try-catch -a cursor -y
Gemini CLI
$ npx skills add growthxai/output --skill output-error-try-catch -a gemini-cli -y
GitHub Copilot
$ npx skills add growthxai/output --skill output-error-try-catch -a github-copilot -y
OpenCode
$ npx skills add growthxai/output --skill output-error-try-catch -a opencode -y
Windsurf
$ npx skills add growthxai/output --skill output-error-try-catch -a windsurf -y
name: output-error-try-catch description: Handle errors caught in Output workflows without losing failure context. Use when adding workflow try/catch logic, fallbacks, partial-failure handling, custom Error classes, or typed checks for errors thrown by steps and evaluators. allowed-tools: [Bash, Read, Write, Edit]
Steps and evaluators run as Temporal Activities. Temporal applies their configured retry policy before returning a successful result or throwing a final failure to workflow code.
A workflow `catch` around a step therefore runs only after the step has exhausted its Activity retries. Catching that failure does not disable or bypass the Activity retry policy.
The catch block decides what the workflow does with the final failure:
Do not add a catch block that only wraps or logs an error. It can discard Temporal's failure type, cause chain, and retry metadata.
// Avoid: replaces the original Temporal failure chain.
try {
return await fetchData( input );
} catch ( error ) {
throw new Error( `Fetch failed: ${error.message}` );
}When the workflow cannot recover, let the step failure propagate:
export default workflow( {
name: 'fetch_workflow',
fn: async input => fetchData( input )
} );If a catch block handles only known failures, always rethrow everything else.
Errors crossing from a step or evaluator into workflow code are serialized into a Temporal failure cause chain. The original JavaScript object identity is not preserved, so `error instanceof CustomError` is unreliable.
Use `hasErrorType` from `@outputai/core`. It walks the cause chain and matches native instances and Temporal's serialized `type` and `name` fields.
import { hasErrorType, workflow } from '@outputai/core';
import { lookupCompany } from './steps.js';
import { CompanyNotFoundError } from './types.js';
export default workflow( {
name: 'company_lookup',
fn: async input => {
try {
return await lookupCompany( input );
} catch ( error ) {
if ( hasErrorType( error, CompanyNotFoundError ) ) {
return null;
}
throw error;
}
}
} );Define custom Error classes in a shared module imported by both the workflow and step:
export class CompanyNotFoundError extends Error {}Do not inspect a fixed number of `.cause` levels or check only the outer `ActivityFailure`.
const fetchWithFallback = async input => {
try {
return await fetchFromPrimarySource( input );
} catch {
return fetchFromSecondarySource( input );
}
};Use this only when every primary-source failure should trigger the fallback. Use `hasErrorType` when only specific failures are recoverable.
const results = await Promise.all( input.items.map( async item => {
try {
return { item, value: await processItem( item ), ok: true };
} catch ( error ) {
const message = error instanceof Error ? error.message : String( error );
return { item, error: message, ok: false };
}
} ) );Ensure the workflow output schema supports both successful and failed entries. Do not silently omit failures.
Configure step and evaluator retry behavior through workflow Activity options. The workflow catch block handles only the failure that remains after this policy is exhausted.
export default workflow( {
name: 'company_lookup',
fn: async input => lookupCompany( input ),
options: {
activityOptions: {
retry: {
initialInterval: '1s',
maximumAttempts: 3
}
}
}
} );The open-source TypeScript framework for building AI workflows and agents. Designed for Claude Code — describe what you want, Claude builds it, with all the best practices already in place. One framework.
Implement an Output SDK workflow from a plan document. Use when the user asks to build, implement, or code a workflow from an…
View, edit, and set encrypted credentials in an Output.ai project. Use when adding secrets, updating API keys, verifying…
Wire encrypted credentials to environment variables using the credential: convention. Use when setting up LLM provider keys…
Initialize encrypted credentials for an Output.ai project. Use when setting up credentials for the first time, adding…
Debug Output SDK workflow issues. Use when user reports a workflow failing, erroring, hanging, producing wrong results, or asks…
Use the Agent class for multi-step tool loops, conversation history, streaming progress, and reusable LLM agents. Use when…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.