abi/screenshot-to-code · error · ValueError
HTTP error occurred: {exc}
Error message
HTTP error occurred: {exc} What it means
Wrapped error from _run_prediction: an httpx.HTTPStatusError (a 4xx/5xx HTTP response, surfaced by raise_for_status) is re-raised as ValueError with the exception text appended. The original status code, URL, and response are preserved via `from exc`. It fires for both the creation POST and every polling GET.
Source
Thrown at backend/image_generation/replicate.py:93
async def _run_prediction(
endpoint_url: str, payload: dict[str, Any], api_token: str
) -> Any:
headers = _build_headers(api_token)
async with httpx.AsyncClient() as client:
try:
response = await client.post(endpoint_url, headers=headers, json=payload)
response.raise_for_status()
response_json = response.json()
if not isinstance(response_json, dict):
raise ValueError("Invalid prediction creation response.")
prediction_id = _extract_prediction_id(response_json)
final_response = await _poll_prediction(client, prediction_id, headers)
return final_response.get("output")
except httpx.HTTPStatusError as exc:
raise ValueError(f"HTTP error occurred: {exc}") from exc
except httpx.RequestError as exc:
raise ValueError(f"An error occurred while requesting: {exc}") from exc
except asyncio.TimeoutError as exc:
raise TimeoutError("Request timed out") from exc
except (TimeoutError, ValueError):
raise
except Exception as exc:
raise ValueError(f"An unexpected error occurred: {exc}") from exc
def _extract_output_url(result: Any, context: str) -> str:
if isinstance(result, str):
return result
if isinstance(result, dict):
url = cast(Any, result.get("url"))
if isinstance(url, str) and url:
return urlView on GitHub (pinned to d026163f58)
Solutions
- Parse the embedded status: 401 → fix the token, 404 → fix model_path, 422 → fix input schema, 429 → back off.
- Inspect `exc.__cause__` (the HTTPStatusError) for the full response body with Replicate's detail message.
- Verify REPLICATE_API_KEY in backend/.env (this key only works via .env, not the UI settings).
- Add rate-limit backoff if firing under parallel requests.
Defensive patterns
Strategy: try-catch
Try / catch
try:
output = await call_replicate_model(model, input, token)
except ValueError as e:
cause = e.__cause__
if isinstance(cause, httpx.HTTPStatusError):
status = cause.response.status_code
if status == 401:
return error("Invalid Replicate API token")
if status == 404:
return error(f"Unknown model: {model}")
if status == 429:
await asyncio.sleep(backoff); retry = True
raise Prevention
- Set REPLICATE_API_KEY in backend/.env and restart — the UI settings dialog can't hold it
- Verify model_path spelling (owner/name[:version]) against the Replicate site
- Handle 401/404/429 distinctly: only 429 merits retry with backoff
When it happens
Trigger: 401 invalid REPLICATE_API_KEY; 404 unknown model_path; 422 invalid input payload for the model; 429 rate limited. The exc text embeds the status code and server message, e.g. "Client error '401 Unauthorized' for url ...".
Common situations: Expired or mistyped API token; using a model name that was renamed or deleted; exceeding Replicate rate limits under concurrent generation; malformed input JSON the API rejects.
Related errors
- Prediction ID not found in initial response.
- Invalid prediction status response.
- Inference errored out: {error_message}
- Invalid prediction creation response.
- An error occurred while requesting: {exc}
AI-assisted analysis of abi/screenshot-to-code@d026163f58 (2026-08-14).
Data as JSON: /api/errors/ef5d94bdadcb7a70.
Report an issue: GitHub.