• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialdevelopment

output-error-missing-schemas

プラグイン
outputai
ソース
GitHub で見る ↗
説明

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(出力スキーマ)の定義がないステップによって引き起こされる問題の診断と修正を支援します。スキーマは、型安全性、データの検証、そしてステップ間での適切なデータ変換に不可欠です。

次のような場合に使用

以下のような状況が発生している場合:

  • ステップの境界で型エラーが出ている
  • ステップの入出力に未定義のプロパティが存在する
  • ステップ間でデータを渡す際に検証が失敗する
  • TypeScript でエラーが出て型が一致していない
  • 実行時に予期しないデータ形式についてのエラーが出ている

根本原因

スキーマが明示的に定義されていないステップは:

  • 実行時に入力データを検証しない
  • TypeScript の型推論(自動型認識)が機能しない
  • データが正しく変換・復元されない可能性がある
  • 不正なデータやデータの欠落を見落としたまま処理してしまう

よくある症状

入力スキーマが欠落している

// 間違い: 入力の検証がない
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/

各ステップ定義を確認して、両方のスキーマが存在することを確認してください。

明示的なスキーマの利点

  1. 実行時の検証: データエラーを早期に検出
  2. 型安全性: ステップ関数内で完全な TypeScript 型推論
  3. ドキュメント化: スキーマが期待されるデータの形式を明確に示す
  4. データ変換: ステップ間でのデータ変換が正確に行われることを保証
  5. エラーメッセージ: データが正しくない場合に明確な検証エラーを表示

よくあるスキーマのパターン

API データ取得ステップ

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 };
  }
} );

動作確認

スキーマを追加した後:

  1. TypeScript チェック: npm run output:worker:build がエラーなく通ること
  2. 実行時テスト: npx output workflow run <name> --input '<input>' が正しく検証されること
  3. 不正なデータテスト: 不正なデータを渡して、検証エラーが表示されることを確認

関連する問題

  • Zod(バリデーション・ライブラリ)のインポートについては、output-error-zod-import を参照
  • スキーマがあるのに型が一致しない場合は、スキーマが実際のデータと合致しているか確認してください
原文(English)を表示

Fix Missing Schema Definitions

Overview

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.

When to Use This Skill

You're seeing:

  • Type errors at step boundaries
  • Undefined properties in step inputs/outputs
  • Validation failures when passing data between steps
  • TypeScript errors about incompatible types
  • Runtime errors about unexpected data shapes

Root Cause

Steps without explicit schemas:

  • Don't validate input data at runtime
  • Don't provide TypeScript type inference
  • May serialize/deserialize data incorrectly
  • Can pass undefined or malformed data silently

Symptoms

Missing Input Schema

// 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!
  }
} );

Missing Output Schema

// 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
  }
} );

Both Schemas Missing

// WRONG: No validation at all
export const transformData = step( {
  name: 'transformData',
  // No schemas!
  fn: async input => {
    return transform( input );
  }
} );

Solution

Always define both inputSchema and outputSchema for every step:

Complete Step Definition

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
  }
} );

Schema Definition Best Practices

Use Descriptive Schemas

// Good: Clear, descriptive schema
inputSchema: z.object( {
  userId: z.string().uuid(),
  email: z.string().email(),
  age: z.number().int().positive()
} )

Handle Optional Fields

inputSchema: z.object( {
  required: z.string(),
  optional: z.string().optional(),
  withDefault: z.string().default( 'fallback' )
} )

Use Schema Composition

// 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
} )

Handle Arrays and Nested Objects

inputSchema: z.object( {
  items: z.array( z.object( {
    id: z.string(),
    quantity: z.number()
  } ) ),
  metadata: z.record( z.string() )
} )

Finding Steps Without Schemas

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.

Benefits of Explicit Schemas

  1. Runtime Validation: Catches data errors early
  2. Type Safety: Full TypeScript inference in step functions
  3. Documentation: Schemas document expected data shapes
  4. Serialization: Ensures proper data serialization between steps
  5. Error Messages: Clear validation errors when data is wrong

Common Schema Patterns

API Response Steps

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 };
  }
} );

Transformation Steps

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 };
  }
} );

Void Output Steps

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 };
  }
} );

Verification

After adding schemas:

  1. TypeScript check: npm run output:worker:build should pass without type errors
  2. Runtime test: npx output workflow run <name> --input '<input>' should validate correctly
  3. Invalid input test: Pass invalid data and verify validation errors appear

Related Issues

  • For Zod import issues, see output-error-zod-import
  • For type mismatches despite schemas, verify schema matches actual data

原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。