ZhuLinsen/daily_stock_analysis · error · ValueError
图片内容为空
Error message
图片内容为空
What it means
Simple guard in extract_stock_codes_from_image: image_bytes is empty (falsy) after MIME validation passed. The function refuses to base64-encode and call the vision API on an empty payload.
Source
Thrown at src/services/image_stock_extractor.py:370
优先级:Gemini -> Anthropic -> OpenAI(首个可用)。
支持多 Key 轮询与重试(最多 3 次,指数退避)。
Args:
image_bytes: 原始图片字节
mime_type: MIME 类型(如 image/jpeg, image/png)
Returns:
(items, raw_text) - items 为 [(code, name?, confidence), ...],raw_text 为原始 LLM 响应。
Raises:
ValueError: 图片无效、未配置 Vision API 或提取失败时。
"""
mime_type = (mime_type or "image/jpeg").strip().lower().split(";")[0].strip()
if mime_type not in ALLOWED_MIME:
raise ValueError(f"不支持的图片类型: {mime_type}。允许: {list(ALLOWED_MIME)}")
if not image_bytes:
raise ValueError("图片内容为空")
if len(image_bytes) > MAX_SIZE_BYTES:
raise ValueError(f"Image too large (max {MAX_SIZE_BYTES // (1024 * 1024)}MB)")
_verify_image_magic_bytes(image_bytes, mime_type)
image_b64 = base64.b64encode(image_bytes).decode("ascii")
model = _resolve_vision_model()
keys = _get_api_keys_for_model(model, get_config())
last_error: Optional[Exception] = None
for attempt in range(3):
try:
key = random.choice(keys) if keys else None
raw = _call_litellm_vision(image_b64, mime_type, api_key=key)
logger.debug("[ImageExtractor] raw LLM response:\n%s", raw)
items = _parse_items_from_text(raw)
logger.info(View on GitHub (pinned to 5159bd72e8)
Solutions
- Check the upload path: verify file.size > 0 before submitting
- Verify the read: seek(0) before .read() if reusing a file handle
- Add client-side validation rejecting empty files
Example fix
# before
with open(p,'rb') as f: data = f.read() # f at EOF -> b''
items, raw = extract_stock_codes_from_image(data, 'image/png')
# after
with open(p,'rb') as f:
f.seek(0)
data = f.read()
assert data, 'empty file'
items, raw = extract_stock_codes_from_image(data, 'image/png') Defensive patterns
Strategy: validation
Validate before calling
if not image_bytes:
raise ValueError('上传文件为空,请重新选择文件')
# or: if uploaded.size == 0: reject Type guard
def has_image_payload(b: bytes | None) -> bool:
return isinstance(b, (bytes, bytearray)) and len(b) > 0 Prevention
- Reject 0-byte files at the upload form (file.size > 0)
- seek(0) before read() when reusing file handles
- Never fire the extraction request when the client-side File object is empty
When it happens
Trigger: Calling with b'' or None as image_bytes; upstream file read returning empty bytes (0-byte upload, truncated multipart part).
Common situations: Front-end sending an empty FormData entry; file handle read after position exhausted; race where upload file was deleted before read completed.
Related errors
- unsupported_type
- file_too_large
- 不支持的图片类型: {mime_type}。允许: {list(ALLOWED_MIME)}
- Image too large (max {MAX_SIZE_BYTES // (1024 * 1024)}MB)
- Backend executable not found: ${backendPath}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/480aab3cf8072255.
Report an issue: GitHub.