{"record":{"id":"24762dee554e9925","repo":"srbhr/Resume-Matcher","slug":"no-json-found-in-response-original-200","errorCode":null,"errorMessage":"No JSON found in response: {original[:200]}","messagePattern":"No JSON found in response: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"apps/backend/app/llm.py","lineNumber":1181,"sourceCode":"                \"JSON extraction found unbalanced braces (depth=%d), possible truncation\",\n                depth,\n            )\n\n        if end_idx != -1:\n            return content[: end_idx + 1]\n\n    # Try to find JSON object in the content (only if not already at start)\n    start_idx = content.find(\"{\")\n    if start_idx > 0:\n        # Only recurse if { is found after position 0 to avoid infinite recursion\n        return _extract_json(content[start_idx:], _depth + 1)\n\n    # LLM-007: Log unrecognized format for debugging\n    logging.error(\n        \"Could not extract JSON from response format. Content preview: %s\",\n        content[:200] if content else \"<empty>\",\n    )\n    raise ValueError(f\"No JSON found in response: {original[:200]}\")\n\n\nasync def complete_json(\n    prompt: str,\n    system_prompt: str | None = None,\n    config: LLMConfig | None = None,\n    max_tokens: int = 4096,\n    retries: int = 2,\n    schema_type: str = \"resume\",\n) -> dict[str, Any]:\n    \"\"\"Make a completion request expecting JSON response.\n\n    Uses JSON mode when available, with app-level retries for content-quality\n    issues (malformed JSON, truncation).  Transport retries (429, 500, timeout)\n    are handled by the Router and are NOT retried again here.\n\n    Args:\n        schema_type: Expected schema — \"resume\", \"enrichment\", \"diff\",","sourceCodeStart":1163,"sourceCodeEnd":1199,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/backend/app/llm.py#L1163-L1199","documentation":"After stripping think tags, extracting code fences, and locating JSON boundaries, _extract_json raises this ValueError when no JSON structure can be found at all in the model response. It also logs a 200-char preview of the unrecognized format (LLM-007) for debugging.","triggerScenarios":"complete_json receives a response containing no parseable JSON object/array — the model answered in plain prose, refused the task, or wrapped output in an unrecognized format the extractor doesn't handle.","commonSituations":"Weak/small model ignoring 'output JSON only' instructions; model safety-refuses the prompt; prompt ambiguous so the model narrates instead of emitting JSON; non-JSON-mode model where response_format is unsupported.","solutions":["Strengthen the prompt: 'Respond with ONLY a valid JSON object. Start with { and end with }.'","Use a model/provider that supports JSON mode (see _supports_json_mode) so response_format json_object is enforced","Check the logged 'Could not extract JSON from response format. Content preview:' line to see what the model actually returned","Retry with a stronger model or lower temperature; complete_json already retries with a corrective suffix"],"exampleFix":"// before\nconst prompt = 'List the skills in this resume.';\n// after\nconst prompt = 'List the skills in this resume. Respond with ONLY a JSON object like {\"skills\": [...]}. No prose.';","handlingStrategy":"retry","validationCode":"import json, re\ndef looks_like_json(s: str) -> bool:\n    s = s.strip()\n    if s.startswith(\"```\"): \n        s = re.sub(r\"^```[a-z]*\\n|```$\", \"\", s).strip()\n    return s.startswith((\"{\", \"[\")) and bool(_try_loads(s))\n\ndef _try_loads(s):\n    try: json.loads(s)\n    except Exception: return None\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    data = await complete_json(prompt)\nexcept ValueError as e:\n    if e.message.starts with \"No JSON found\":\n        # inspect logged content preview, then retry with stricter instruction\n        data = await complete_json(prompt + \"\\nOutput ONLY raw JSON. No markdown, no explanation.\")\n    else:\n        raise","preventionTips":["End prompts with an explicit JSON-only instruction and a schema example","Use a JSON-mode-capable model so response_format is enforced","Check the logged 'Content preview' to diagnose recurring bad formats","Prefer lower temperature for structured-output requests"],"tags":["llm","json","malformed-response","backend"],"backgroundTag":"no-json-in-llm-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}