SubtitleEdit/subtitleedit · error · Exception

{StaticName} failed with status code {(int)result.StatusCode

Error message

{StaticName} failed with status code {(int)result.StatusCode} ({result.StatusCode}) - free API quota exceeded?

 {jsonResultString}

What it means

Thrown by GoogleTranslateV1 when the free, unofficial Google translate endpoint (translate.googleapis.com/translate_a/single with client=gtx) returns a non-success HTTP status. This endpoint is undocumented and rate-limited; Google throttles or blocks it aggressively, hence the 'free API quota exceeded?' guess in the message.

Source

Thrown at src/libuilogic/AutoTranslate/GoogleTranslateV1.cs:66

        public async Task<string> Translate(string input, string sourceLanguageCode, string targetLanguageCode, CancellationToken cancellationToken)
        {
            string jsonResultString;

            try
            {
                var text = input.Replace("\r", string.Empty).Trim();
                var url = $"translate_a/single?client=gtx&sl={sourceLanguageCode}&tl={targetLanguageCode}&dt=t&q={Utilities.UrlEncode(text)}";

                var result = await _httpClient.GetAsync(url, cancellationToken);
                var bytes = await result.Content.ReadAsByteArrayAsync(cancellationToken);
                jsonResultString = Encoding.UTF8.GetString(bytes).Trim();

                if (!result.IsSuccessStatusCode)
                {
                    Error = jsonResultString;
                    SeLogger.Error($"Error in {StaticName}.Translate: " + Error);
                    throw new Exception($"{StaticName} failed with status code {(int)result.StatusCode} ({result.StatusCode}) - free API quota exceeded?" + Environment.NewLine + Environment.NewLine + jsonResultString);
                }
            }
            catch (WebException webException)
            {
                throw new Exception("Free API quota exceeded?", webException);
            }

            var resultList = ConvertJsonObjectToStringLines(jsonResultString);
            return string.Join(Environment.NewLine, resultList);
        }

        public static List<TranslationPair> GetTranslationPairs()
        {
            return new List<TranslationPair>
            {
                new TranslationPair("AFAR", "aa"),
                new TranslationPair("AFRIKAANS", "af"),
                new TranslationPair("ALBANIAN", "sq"),

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Slow down: add delays between requests to stay under Google's per-IP rate limit.
  2. Switch to GoogleTranslateV2 (official API with key) for reliable bulk translation.
  3. Rotate off a flagged IP (disable VPN/proxy, or use a residential proxy).
  4. Reduce batch sizes and retry after a cooldown.

Example fix

// before
throw new Exception($"{StaticName} failed with status code {(int)result.StatusCode} ({result.StatusCode}) - free API quota exceeded?" + Environment.NewLine + Environment.NewLine + jsonResultString);

// after - branch on 429 so callers can back off rather than treat it as fatal
if ((int)result.StatusCode == 429)
{
    throw new Exception($"{StaticName} rate-limited (429) by Google's free endpoint - slow down or use GoogleTranslateV2 with an API key.");
}
throw new Exception($"{StaticName} failed with status code {(int)result.StatusCode} ({result.StatusCode}) - free API quota exceeded?" + Environment.NewLine + Environment.NewLine + jsonResultString);
Defensive patterns

Strategy: retry

Validate before calling

// Google's free endpoint throttles hard; enforce a client-side rate limit before calling
private static readonly TimeSpan MinInterval = TimeSpan.FromMilliseconds(1200);
private static DateTime _lastCall = DateTime.MinValue;
public async Task<string> TranslateThrottled(...)
{
    var wait = MinInterval - (DateTime.UtcNow - _lastCall);
    if (wait > TimeSpan.Zero) await Task.Delay(wait, token);
    try { return await v1.Translate(text, src, tgt, token); }
    finally { _lastCall = DateTime.UtcNow; }
}

Try / catch

for (int attempt = 0; attempt < 4; attempt++)
{
    try { return await googleV1.Translate(text, src, tgt, token); }
    catch (Exception ex) when (ex.Message.Contains("429") || ex.Message.Contains("quota exceeded"))
    {
        await Task.Delay(TimeSpan.FromSeconds(5 * (attempt + 1)), token);
    }
}
throw new InvalidOperationException("Google free endpoint kept rate-limiting after retries - use GoogleTranslateV2.");

Prevention

When it happens

Trigger: Translate() builds a GET to translate_a/single?client=gtx&...&q=<encoded text>; the response status is not success. Most commonly HTTP 429 Too Many Requests, but also 403/503 when Google detects automated use, or 502 from a proxy.

Common situations: Bulk-translating many lines quickly triggers Google's per-IP throttle; behind a shared/NAT IP that other automated clients also hit; proxy or VPN IP already flagged; using a User-Agent that looks automated (the code sets a Chrome UA at line 34, which helps but is not bulletproof).

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/50f29ad8dd99351c. Report an issue: GitHub.