{"record":{"id":"88f4ad458a114b69","repo":"sickn33/agentic-awesome-skills","slug":"openai-api-error-err-msg","errorCode":null,"errorMessage":"OpenAI API error: {err_msg}","messagePattern":"OpenAI API error: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"skills/last30days/scripts/lib/openai_reddit.py","lineNumber":156,"sourceCode":"    return http.post(OPENAI_RESPONSES_URL, payload, headers=headers, timeout=timeout)\n\n\ndef parse_reddit_response(response: Dict[str, Any]) -> List[Dict[str, Any]]:\n    \"\"\"Parse OpenAI response to extract Reddit items.\n\n    Args:\n        response: Raw API response\n\n    Returns:\n        List of item dicts\n    \"\"\"\n    items = []\n\n    # Check for API errors first\n    if \"error\" in response and response[\"error\"]:\n        error = response[\"error\"]\n        err_msg = error.get(\"message\", str(error)) if isinstance(error, dict) else str(error)\n        _log_error(f\"OpenAI API error: {err_msg}\")\n        if http.DEBUG:\n            _log_error(f\"Full error response: {json.dumps(response, indent=2)[:1000]}\")\n        return items\n\n    # Try to find the output text\n    output_text = \"\"\n    if \"output\" in response:\n        output = response[\"output\"]\n        if isinstance(output, str):\n            output_text = output\n        elif isinstance(output, list):\n            for item in output:\n                if isinstance(item, dict):\n                    if item.get(\"type\") == \"message\":\n                        content = item.get(\"content\", [])\n                        for c in content:\n                            if isinstance(c, dict) and c.get(\"type\") == \"output_text\":\n                                output_text = c.get(\"text\", \"\")","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/sickn33/agentic-awesome-skills/blob/58d857988fcfac6986206bca2b2fe223aa437e4b/skills/last30days/scripts/lib/openai_reddit.py#L138-L174","documentation":"parse_reddit_response logs this when the JSON body from the OpenAI Responses API (POST to OPENAI_RESPONSES_URL with the web_search tool limited to reddit.com) contains a truthy top-level 'error' field. It logs error.message (or the stringified error) and returns an empty list, so the failure appears downstream as zero Reddit items rather than an exception. Typical causes: auth, quota/billing, model access, or a rejected request payload.","triggerScenarios":"Calling the Reddit fetch with an invalid/expired bearer key (401 error body), an org out of quota or with billing disabled (429/402), a model name that does not exist or lacks Responses/web_search support, or a malformed payload/oversized prompt. In each case http.post still returns a JSON body whose 'error' key triggers the log and an empty list.","commonSituations":"Wrong or rotated OPENAI_API_KEY in the environment; typo'd or deprecated model passed via --model; billing disabled so every call errors; using the web_search tool against a model or base URL that does not support it; empty report sections mistaken for 'no Reddit posts found' when the API actually failed.","solutions":["Run with http.DEBUG enabled to print the full error body — the message names the code (invalid_api_key, model_not_found, rate_limit_exceeded, insufficient_quota).","Verify OPENAI_API_KEY: correct value, no whitespace, account active; smoke-test with a minimal curl to /v1/responses.","Check the model argument: use a current Responses-API model that supports web_search; fix typos and deprecated names.","If the message cites rate limits or quota, check org billing/credits, back off, and retry after the window.","Because the function returns [] on error, treat empty results as suspect and surface API errors to the caller instead of silently continuing."],"exampleFix":"# before: error swallowed; caller cannot tell 'no results' from 'API error'\nif \"error\" in response and response[\"error\"]:\n    _log_error(f\"OpenAI API error: {err_msg}\")\n    return items\n\n# after: raise so the caller can retry or report\nif \"error\" in response and response[\"error\"]:\n    raise RuntimeError(f\"OpenAI API error: {err_msg}\")","handlingStrategy":"try-catch","validationCode":"# Validate key and model before calling the API\nimport re\n\ndef precheck_openai(api_key: str, model: str) -> None:\n    if not api_key or not re.fullmatch(r'sk-[A-Za-z0-9_-]+', api_key):\n        raise ValueError('OPENAI_API_KEY is missing or malformed')\n    if not model or not model.startswith('gpt-'):\n        raise ValueError(f'Unsupported Responses model: {model}')","typeGuard":"from typing import Any, Dict\n\ndef is_openai_error_response(response: Dict[str, Any]) -> bool:\n    \"\"\"True when the Responses API returned an error body.\"\"\"\n    return bool(response.get(\"error\"))\n\ndef has_output_items(response: Dict[str, Any]) -> bool:\n    return isinstance(response.get(\"output\"), list) and len(response[\"output\"]) > 0","tryCatchPattern":"items = parse_reddit_response(response)  # returns [] on error\n# Instead, inspect the body explicitly:\nif response.get(\"error\"):\n    msg = response[\"error\"].get(\"message\", str(response[\"error\"]))\n    if any(k in msg for k in ('rate_limit', 'quota')):\n        time.sleep(backoff)  # then retry once\n    else:\n        raise RuntimeError(f'OpenAI API error: {msg}')  # never report empty as 'no results'","preventionTips":["Smoke-test the API key and model with a one-line request before running a full last30days report.","Keep DEBUG enabled during development to capture full error bodies.","Never interpret an empty items list as 'no results' without first confirming the response has no 'error' key.","Pin model names to a known-good Responses model and review OpenAI deprecation notices."],"tags":["python","openai","api-error","responses-api","reddit","last30days"],"backgroundTag":"llm-api-error-response","analyzedSha":"58d857988fcfac6986206bca2b2fe223aa437e4b","analyzedAt":"2026-08-26T11:55:59.350Z","schemaVersion":2},"datasetVersion":"2026-08-26T14:46:13.012Z"}