← All guides

Claude API vision_error (invalid_request_error): 원인과 해결법

Claude API vision_error invalid_request_error 해결: 이미지 입력 오류 · 재시도 비효과

Claude API vision_error (invalid_request_error): 원인과 해결법

Claude API vision_error invalid_request_error는 이미지 형식, 크기, 또는 인코딩이 모델 요구사항과 불일치에 발생합니다. 이미지 입력 오류이며, 재시도하지 말고 요청 자체를 수정해야 합니다. 이 글은 5가지 흔한 원인과 Python/TypeScript 코드 예시를 다룹니다.

전반적인 Claude API 에러 처리 패턴은 Claude API Error Handling 가이드를 참고하세요.


무엇을 의미하는가?

vision_error 에러 서브타입는 이미지 형식, 크기, 또는 인코딩이 모델 요구사항과 불일치을 의미합니다. Anthropic API의 에러 응답 본문에는 error.type"invalid_request_error"로 명시되며, error.message에 구체적 사유가 옵니다.

응답 예시:

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "..."
  }
}

흔한 원인 5가지

  1. 지원 안 되는 이미지 포맷 (예: WebP, BMP — JPEG/PNG/GIF/WebP만)
  2. 단일 이미지 5MB 초과 (base64 인코딩 후)
  3. 이미지 dimensions 8000×8000 초과
  4. URL 이미지의 Content-Type이 image/* 아님

해결 코드 (Python)

# Validate image before sending
from PIL import Image
import io, base64

def safe_image_block(image_bytes: bytes):
    img = Image.open(io.BytesIO(image_bytes))
    if img.format not in ("JPEG", "PNG", "GIF", "WEBP"):
        raise ValueError(f"Unsupported format: {img.format}")
    if img.size[0] > 8000 or img.size[1] > 8000:
        # Resize down
        img.thumbnail((8000, 8000))
    if len(image_bytes) > 5_000_000:
        # Compress
        buf = io.BytesIO()
        img.save(buf, format="JPEG", quality=85)
        image_bytes = buf.getvalue()
    return {
        "type": "image",
        "source": {
            "type": "base64",
            "media_type": f"image/{img.format.lower()}",
            "data": base64.b64encode(image_bytes).decode(),
        },
    }

해결 코드 (TypeScript)

import sharp from "sharp";

async function safeImageBlock(buf: Buffer) {
  let img = sharp(buf);
  const meta = await img.metadata();
  if (!["jpeg", "png", "gif", "webp"].includes(meta.format ?? "")) {
    throw new Error(`Unsupported: ${meta.format}`);
  }
  if ((meta.width ?? 0) > 8000 || (meta.height ?? 0) > 8000) {
    img = img.resize(8000, 8000, { fit: "inside" });
  }
  let out = await img.toBuffer();
  if (out.length > 5_000_000) {
    out = await sharp(buf).jpeg({ quality: 85 }).toBuffer();
  }
  return {
    type: "image",
    source: {
      type: "base64",
      media_type: `image/${meta.format}`,
      data: out.toString("base64"),
    },
  };
}

재시도하지 마세요

이 에러는 클라이언트 측 문제라 재시도해도 같은 결과입니다. 위 원인을 확인하고 요청을 수정한 뒤 재발송하세요.


비용 영향

이 에러는 요청이 처리되지 않았으므로 비용이 청구되지 않습니다. 단, 잘못된 모델로 요청을 반복하다가 다른 에러가 발생할 수 있으니 모니터링이 필요합니다.

자세한 비용 절감 패턴은 Claude API Cost and Prompt Caching Break-Even 또는 무료 비용 계산기를 참고하세요.


관련 에러


자주 묻는 질문

vision_error 에러가 떴을 때 비용이 청구되나요?

처리되지 않은 요청이므로 청구되지 않습니다. 단, 무한 재시도 루프는 다른 에러로 비용을 발생시킬 수 있습니다.

vision_error와 다른 에러의 차이는?

vision_error는 클라이언트 측 문제로 요청 수정 없이는 재시도해도 같은 결과입니다. 5xx 에러 (500/529)는 일시적 서버 이슈라 재시도가 효과적입니다.

Bedrock/Vertex에서도 같은 에러 코드인가요?

네, Anthropic의 error.type 명명 규칙은 모든 deployment (Direct API, AWS Bedrock, GCP Vertex AI)에서 동일합니다. 다만 HTTP 상태 코드는 platform 별로 wrapping되어 다를 수 있습니다 (예: Bedrock은 에러 type을 다른 prefix로 변경).


다음 단계

에러 처리 패턴 30개 + Pydantic 검증 코드Claude API Cost Optimization 마스터클래스 ($59)에 retry 미들웨어, 비용 가드레일, 에러 알림 패턴 12편 포함.

Tools and references