Fix HTTP client misuse in Output SDK steps. Use when seeing untraced requests, missing error details, axios-related errors, or when HTTP calls aren't being properly logged and retried.
Detects when you use axios or fetch directly in Output SDK steps instead of the httpClient from @output.ai/http. Automatically fixes these calls to use the proper SDK client, which provides tracing, automatic retries, and standardized error handling.
/plugin marketplace add growthxai/output-claude-plugins/plugin install growthxai-outputai-plugins-outputai@growthxai/output-claude-pluginsThis skill is limited to using the following tools:
This skill helps diagnose and fix issues caused by using axios, fetch, or other HTTP clients directly instead of Output SDK's httpClient from @output.ai/http. The Output SDK client provides tracing, automatic retries, and better error handling.
You're seeing:
Using axios, fetch, or other HTTP clients directly bypasses Output SDK's:
// WRONG: Using axios
import axios from 'axios';
export const fetchData = step({
name: 'fetchData',
fn: async (input) => {
const response = await axios.get('https://api.example.com/data');
return response.data;
},
});
// WRONG: Using fetch
export const fetchData = step({
name: 'fetchData',
fn: async (input) => {
const response = await fetch('https://api.example.com/data');
return response.json();
},
});
Use httpClient from @output.ai/http:
import { z, step } from '@output.ai/core';
import { httpClient } from '@output.ai/http';
export const fetchData = step({
name: 'fetchData',
inputSchema: z.object({
endpoint: z.string(),
}),
outputSchema: z.object({
data: z.unknown(),
}),
fn: async (input) => {
const client = httpClient({
prefixUrl: 'https://api.example.com',
});
const data = await client.get(input.endpoint).json();
return { data };
},
});
import { httpClient } from '@output.ai/http';
const client = httpClient({
prefixUrl: 'https://api.example.com',
timeout: 30000, // 30 second timeout
retry: {
limit: 3, // Retry up to 3 times
methods: ['GET', 'POST'], // Which methods to retry
statusCodes: [408, 500, 502, 503, 504], // Which status codes trigger retry
},
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
});
const data = await client.get('users/123').json();
const result = await client.post('users', {
json: {
name: 'John',
email: 'john@example.com',
},
}).json();
const updated = await client.put('users/123', {
json: {
name: 'John Updated',
},
}).json();
await client.delete('users/123');
const data = await client.get('search', {
searchParams: {
q: 'query',
limit: 10,
},
}).json();
import axios from 'axios';
import { step } from '@output.ai/core';
export const createUser = step({
name: 'createUser',
fn: async (input) => {
try {
const response = await axios.post(
'https://api.example.com/users',
{ name: input.name, email: input.email },
{
headers: { 'Authorization': `Bearer ${process.env.API_KEY}` },
timeout: 30000,
}
);
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(`API Error: ${error.response?.data?.message}`);
}
throw error;
}
},
});
import { z, step } from '@output.ai/core';
import { httpClient } from '@output.ai/http';
export const createUser = step({
name: 'createUser',
inputSchema: z.object({
name: z.string(),
email: z.string().email(),
}),
outputSchema: z.object({
id: z.string(),
name: z.string(),
email: z.string(),
}),
fn: async (input) => {
const client = httpClient({
prefixUrl: 'https://api.example.com',
timeout: 30000,
retry: { limit: 3 },
headers: {
'Authorization': `Bearer ${process.env.API_KEY}`,
},
});
const user = await client.post('users', {
json: {
name: input.name,
email: input.email,
},
}).json();
return user;
},
});
The httpClient provides structured error handling:
import { httpClient, HTTPError } from '@output.ai/http';
export const fetchData = step({
name: 'fetchData',
fn: async (input) => {
const client = httpClient({ prefixUrl: 'https://api.example.com' });
try {
return await client.get('data').json();
} catch (error) {
if (error instanceof HTTPError) {
// Access response details
const status = error.response.status;
const body = await error.response.json();
throw new Error(`API returned ${status}: ${body.message}`);
}
throw error;
}
},
});
Search your codebase:
# Find axios imports
grep -rn "from 'axios'\|from \"axios\"" src/
# Find fetch calls
grep -rn "await fetch(" src/
# Find other HTTP libraries
grep -rn "got\|node-fetch\|request\|superagent" src/
| Option | Description | Default |
|---|---|---|
prefixUrl | Base URL for all requests | (required) |
timeout | Request timeout in ms | 10000 |
retry.limit | Max retry attempts | 2 |
retry.methods | HTTP methods to retry | ['GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'] |
retry.statusCodes | Status codes to retry | [408, 413, 429, 500, 502, 503, 504] |
headers | Default headers | {} |
After migrating to httpClient:
npx output workflow run <name> '<input>'npx output workflow debug <id> --format jsonoutput-error-direct-iooutput-services-checkThis skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.