SubtitleEdit/subtitleedit · error · OcrException
An error occurred calling Cloud Vision API - status code: {r
Error message
An error occurred calling Cloud Vision API - status code: {result.StatusCode} What it means
Thrown by GoogleVisionOcr.Ocr for any non-success HTTP status that is not 400 or 403 — the catch-all branch after the two specific checks. The status code is interpolated into the message.
Source
Thrown at src/ui/Features/Ocr/Engines/GoogleVisionOcr.cs:200
// Do request
var uri = $"?key={apiKey}";
string content;
try
{
var result = await _httpClient.PostAsync(uri, new StringContent(requestBodyString), cancellationToken);
if ((int)result.StatusCode == 400)
{
throw new OcrException("API key invalid (or perhaps billing/API is not enabled)?");
}
if ((int)result.StatusCode == 403)
{
throw new OcrException("\"Perhaps billing is not enabled (or API not enabled or API key is invalid)?\"");
}
if (!result.IsSuccessStatusCode)
{
throw new OcrException($"An error occurred calling Cloud Vision API - status code: {result.StatusCode}");
}
content = await result.Content.ReadAsStringAsync(cancellationToken);
}
catch (HttpRequestException httpException)
{
throw new OcrException("Error calling Cloud Vision API: " + httpException.Message, httpException);
}
return string.Join(Environment.NewLine, JsonToStringList(language, content));
}
public static List<string> JsonToStringList(string language, string content)
{
if (Configuration.Settings.Tools.OcrGoogleCloudVisionSeHandlesTextMerge)
{
var annotations = GetAnnotations(content).ToList();
if (annotations.Count > 0)View on GitHub (pinned to 17a9f07487)
Solutions
- Read result.StatusCode from the message and react: 429 → back off / request quota increase; 5xx → retry with jitter; 404 → fix the base address.
- For rate limits, throttle calls and consider batching images per Vision request.
- Confirm the HttpClient's base address is the Vision annotate endpoint.
- Retry transient 5xx with exponential backoff.
Example fix
// retry on 5xx/429
var policy = Policy.Handle<OcrException>()
.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i)));
await policy.ExecuteAsync(() => ocr.Ocr(bmp, key, lang, ct)); Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try { return await ocr.Ocr(bmp, key, lang, ct); }
catch (OcrException ex) when (ex.Message.Contains("429") || ex.Message.Contains("503")) {
await Task.Delay(TimeSpan.FromSeconds(backoff), ct); return await ocr.Ocr(bmp, key, lang, ct); } Prevention
- Inspect the embedded status code in the message and branch on it.
- Throttle to stay under Vision rate limits; batch images per request.
- Retry 5xx/429 with exponential backoff; surface 4xx permanently.
When it happens
Trigger: result.IsSuccessStatusCode is false AND the status is neither 400 nor 403 (e.g. 401, 404, 429, 500, 503).
Common situations: 429 rate-limit/quota exceeded; 401 unauthorized (expired OAuth-style key); 5xx transient Google outage; 404 wrong endpoint base URL configured on the HttpClient.
Related errors
- An error occurred calling Cloud Vision API - status code: {r
- API key invalid (or perhaps billing/API is not enabled)?
- "Perhaps billing is not enabled (or API not enabled or API k
- Error calling Cloud Vision API: {httpException.Message}
- Lens returned a non-200 status code
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/def9c8dedba7be0e.
Report an issue: GitHub.