{"record":{"id":"e58205852e56a516","repo":"ZhuLinsen/daily_stock_analysis","slug":"no-api-key-found-for-vision-model-model","errorCode":null,"errorMessage":"No API key found for vision model {model}","messagePattern":"No API key found for vision model (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"src/services/image_stock_extractor.py","lineNumber":304,"sourceCode":"        deployment = next(\n            (\n                item\n                for item in deployments\n                if str((item.get(\"litellm_params\") or {}).get(\"api_key\") or \"\").strip() == key\n            ),\n            None,\n        )\n        if deployment is None:\n            deployment = next(\n                (item for item in deployments if _deployment_allows_empty_api_key(item)),\n                None,\n            )\n            if deployment is not None:\n                key = None\n        if deployment is not None:\n            deployment_params = dict(deployment.get(\"litellm_params\") or {})\n    if key is None and not deployment_params:\n        raise ValueError(f\"No API key found for vision model {model}\")\n    wire_model = str(deployment_params.get(\"model\") or model).strip()\n\n    data_url = f\"data:{mime_type};base64,{image_b64}\"\n    call_kwargs: dict = {\n        \"model\": wire_model,\n        \"messages\": [\n            {\n                \"role\": \"user\",\n                \"content\": [\n                    {\"type\": \"text\", \"text\": EXTRACT_PROMPT},\n                    {\"type\": \"image_url\", \"image_url\": {\"url\": data_url}},\n                ],\n            }\n        ],\n        \"max_tokens\": 1024,\n        \"timeout\": VISION_API_TIMEOUT,\n    }\n    effective_api_key = str(deployment_params.get(\"api_key\") or key or \"\").strip()","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/image_stock_extractor.py#L286-L322","documentation":"Raised by _call_litellm_vision in image_stock_extractor.py when no API key resolves for the selected vision model and no LiteLLM deployment provides usable params. The service first tries per-model keys (_get_api_keys_for_model), then LiteLLM deployments (including ones allowing an empty key, e.g. local/Ollama providers). Only when both key sources are empty does it refuse to call the model.","triggerScenarios":"Calling extract_stock_codes_from_image() when the resolved vision model (from _resolve_vision_model(), e.g. gemini/*, gpt-4o*, claude*) has no matching key in config and litellm.get_model_list() contains no deployment whose model matches or allows an empty api_key.","commonSituations":"Vision-related env vars (e.g. GEMINI_API_KEY / OPENAI_API_KEY) missing or misspelled in .env; LiteLLM proxy not configured so deployments list is empty; model name in config not matching any key variable naming convention; running in CI without secrets.","solutions":["Set the API key matching the vision model in .env (e.g. GEMINI_API_KEY for gemini/* models) and restart","Check _get_api_keys_for_model/_resolve_vision_model to confirm which env var name your model maps to","If using a local/proxy model, configure a LiteLLM deployment that allows an empty API key","Verify with a minimal script that the key is loaded into config before calling the extractor"],"exampleFix":"# before: no vision key set, calling extractor raises\nitems, raw = extract_stock_codes_from_image(img_bytes, 'image/png')\n# after: set key in environment/config first\nos.environ['GEMINI_API_KEY'] = '...'\nitems, raw = extract_stock_codes_from_image(img_bytes, 'image/png')","handlingStrategy":"validation","validationCode":"from src.services.image_stock_extractor import _resolve_vision_model, _get_api_keys_for_model\nfrom src.config import get_config\nmodel = _resolve_vision_model()\nkeys = _get_api_keys_for_model(model, get_config())\nif not keys:\n    raise SystemExit(f'Configure an API key for vision model {model} before importing images')","typeGuard":null,"tryCatchPattern":"try:\n    items, raw = extract_stock_codes_from_image(b, mime)\nexcept ValueError as e:\n    if 'No API key found for vision model' in str(e):\n        # config problem — do not retry; prompt user to set key\n        show_config_error(str(e))\n    else:\n        raise","preventionTips":["Set vision model API keys in .env at deploy time and validate them in a startup health check","Expose a preflight endpoint that reports whether any vision key is configured","Fail fast in UI: hide image-import feature when no vision key is available"],"tags":["vision","api-key","litellm","configuration"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}