Output SDKステップのスキーマ定義(データ構造の仕様)の不足を修正します。 次のような場合に使用: 型エラーが表示される、ステップの境界で未定義のプロパティが現れる、検証に失敗する、またはステップの入出力が適切に型指定されていない場合
Fix missing schema definitions in Output SDK steps. Use when seeing type errors, undefined properties at step boundaries, validation failures, or when step inputs/outputs aren't being properly typed.
このスキルは、明示的な inputSchema(入力スキーマ)または outputSchema(出力スキーマ)の定義がないステップによって引き起こされる問題の診断と修正を支援します。スキーマは、型安全性、データの検証、そしてステップ間での適切なデータ変換に不可欠です。
以下のような状況が発生している場合:
スキーマが明示的に定義されていないステップは:
// 間違い: 入力の検証がない
export const processData = step( {
name: 'processData',
// inputSchema: 欠落!
outputSchema: z.object( { result: z.string() } ),
fn: async input => {
return { result: input.value }; // input.value は undefined の可能性がある!
}
} );
// 間違い: 出力の検証がない
export const fetchData = step( {
name: 'fetchData',
inputSchema: z.object( { id: z.string() } ),
// outputSchema: 欠落!
fn: async input => {
return { data: await getFromApi( input.id ) }; // 出力の形式が検証されない
}
} );
// 間違い: 検証がまったくない
export const transformData = step( {
name: 'transformData',
// スキーマがない!
fn: async input => {
return transform( input );
}
} );
すべてのステップに対して、inputSchemaと outputSchemaの両方を必ず定義してください:
import { z, step } from '@outputai/core';
export const processData = step( {
name: 'processData',
inputSchema: z.object( {
id: z.string(),
value: z.number(),
optional: z.string().optional()
} ),
outputSchema: z.object( {
result: z.string(),
processedAt: z.number()
} ),
fn: async input => {
// input は完全に型が決まる: { id: string, value: number, optional?: string }
return {
result: `Processed ${input.id}`,
processedAt: Date.now()
};
// 出力は outputSchema に対して検証される
}
} );
// 良い例: わかりやすく詳細なスキーマ
inputSchema: z.object( {
userId: z.string().uuid(),
email: z.string().email(),
age: z.number().int().positive()
} )
inputSchema: z.object( {
required: z.string(),
optional: z.string().optional(),
withDefault: z.string().default( 'fallback' )
} )
// 再利用可能なスキーマを定義
const userSchema = z.object( {
id: z.string(),
name: z.string()
} );
const addressSchema = z.object( {
street: z.string(),
city: z.string()
} );
// ステップで組み合わせる
inputSchema: z.object( {
user: userSchema,
address: addressSchema
} )
inputSchema: z.object( {
items: z.array( z.object( {
id: z.string(),
quantity: z.number()
} ) ),
metadata: z.record( z.string() )
} )
コードベースを検索してください:
# ステップ定義を探す
grep -rn "step({" src/workflows/
# inputSchema がないステップを探す
grep -A5 "step({" src/workflows/ | grep -B2 "fn:"
# スキーマが存在するか確認
grep -rn "inputSchema:" src/workflows/
grep -rn "outputSchema:" src/workflows/
各ステップ定義を確認して、両方のスキーマが存在することを確認してください。
export const fetchUser = step( {
name: 'fetchUser',
inputSchema: z.object( {
userId: z.string()
} ),
outputSchema: z.object( {
user: z.object( {
id: z.string(),
name: z.string(),
email: z.string()
} ).nullable(), // 見つからない場合に対応
found: z.boolean()
} ),
fn: async input => {
const user = await api.getUser( input.userId );
return { user, found: user !== null };
}
} );
export const transformData = step( {
name: 'transformData',
inputSchema: z.object( {
raw: z.array( z.unknown() )
} ),
outputSchema: z.object( {
processed: z.array( z.object( {
id: z.string(),
value: z.number()
} ) ),
count: z.number()
} ),
fn: async input => {
const processed = input.raw.map( transformItem );
return { processed, count: processed.length };
}
} );
意味のあるデータを返さないステップの場合:
export const logEvent = step( {
name: 'logEvent',
inputSchema: z.object( {
event: z.string(),
data: z.record( z.unknown() )
} ),
outputSchema: z.object( {
logged: z.literal( true )
} ),
fn: async input => {
await logger.log( input.event, input.data );
return { logged: true };
}
} );
スキーマを追加した後:
npm run output:worker:build がエラーなく通ることnpx output workflow run <name> --input '<input>' が正しく検証されることoutput-error-zod-import を参照This skill helps diagnose and fix issues caused by steps that lack explicit inputSchema or outputSchema definitions. Schemas are essential for type safety, validation, and proper data serialization between steps.
You're seeing:
Steps without explicit schemas:
// WRONG: No input validation
export const processData = step( {
name: 'processData',
// inputSchema: missing!
outputSchema: z.object( { result: z.string() } ),
fn: async input => {
return { result: input.value }; // input.value might be undefined!
}
} );
// WRONG: No output validation
export const fetchData = step( {
name: 'fetchData',
inputSchema: z.object( { id: z.string() } ),
// outputSchema: missing!
fn: async input => {
return { data: await getFromApi( input.id ) }; // Output shape not validated
}
} );
// WRONG: No validation at all
export const transformData = step( {
name: 'transformData',
// No schemas!
fn: async input => {
return transform( input );
}
} );
Always define both inputSchema and outputSchema for every step:
import { z, step } from '@outputai/core';
export const processData = step( {
name: 'processData',
inputSchema: z.object( {
id: z.string(),
value: z.number(),
optional: z.string().optional()
} ),
outputSchema: z.object( {
result: z.string(),
processedAt: z.number()
} ),
fn: async input => {
// input is fully typed: { id: string, value: number, optional?: string }
return {
result: `Processed ${input.id}`,
processedAt: Date.now()
};
// output is validated against outputSchema
}
} );
// Good: Clear, descriptive schema
inputSchema: z.object( {
userId: z.string().uuid(),
email: z.string().email(),
age: z.number().int().positive()
} )
inputSchema: z.object( {
required: z.string(),
optional: z.string().optional(),
withDefault: z.string().default( 'fallback' )
} )
// Define reusable schemas
const userSchema = z.object( {
id: z.string(),
name: z.string()
} );
const addressSchema = z.object( {
street: z.string(),
city: z.string()
} );
// Compose in step
inputSchema: z.object( {
user: userSchema,
address: addressSchema
} )
inputSchema: z.object( {
items: z.array( z.object( {
id: z.string(),
quantity: z.number()
} ) ),
metadata: z.record( z.string() )
} )
Search your codebase:
# Find step definitions
grep -rn "step({" src/workflows/
# Look for steps without inputSchema
grep -A5 "step({" src/workflows/ | grep -B2 "fn:"
# Check if schemas are present
grep -rn "inputSchema:" src/workflows/
grep -rn "outputSchema:" src/workflows/
Review each step definition to ensure both schemas are present.
export const fetchUser = step( {
name: 'fetchUser',
inputSchema: z.object( {
userId: z.string()
} ),
outputSchema: z.object( {
user: z.object( {
id: z.string(),
name: z.string(),
email: z.string()
} ).nullable(), // Handle not found
found: z.boolean()
} ),
fn: async input => {
const user = await api.getUser( input.userId );
return { user, found: user !== null };
}
} );
export const transformData = step( {
name: 'transformData',
inputSchema: z.object( {
raw: z.array( z.unknown() )
} ),
outputSchema: z.object( {
processed: z.array( z.object( {
id: z.string(),
value: z.number()
} ) ),
count: z.number()
} ),
fn: async input => {
const processed = input.raw.map( transformItem );
return { processed, count: processed.length };
}
} );
For steps that don't return meaningful data:
export const logEvent = step( {
name: 'logEvent',
inputSchema: z.object( {
event: z.string(),
data: z.record( z.unknown() )
} ),
outputSchema: z.object( {
logged: z.literal( true )
} ),
fn: async input => {
await logger.log( input.event, input.data );
return { logged: true };
}
} );
After adding schemas:
npm run output:worker:build should pass without type errorsnpx output workflow run <name> --input '<input>' should validate correctlyoutput-error-zod-import原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。