Retry, Rate Limits, and Translation Quality
Use this page when translation requests occasionally time out or hit rate limits, or when you need to control API cost and how failures affect an entire batch. It covers retry attempts (cli.attempts), the per-minute request cap (translator.max_requests_per_minute), error ignoring (cli.ignore_errors), and post-translation quality checks. It does not cover translator selection (see Translator selection and languages), prompt and context composition (see Context and prompts), or API candidate slot management, failover/round_robin strategy, cooldown, and recovery (see the API-management pages).
When to use it
- Owned here:
cli.attemptsdecides the retry budget for request transport and content validation;translator.max_requests_per_minutedecides the actual request pacing;cli.ignore_errorsdecides how failures are isolated at the file/batch level;translator.enable_post_translation_checkand the threepost_check_*thresholds decide post-translation quality checks. - Not owned here: adding/removing candidate slots such as
OPENAI_API_KEY/_2/_3, rotation strategy, cooldown, and unavailable states belong to API management;cli.save_quality(Image Save Quality) is output-file compression quality, not translation quality. - High-quality translators (
openai_hq/gemini_hq) and custom prompts affect translation quality but belong to the translator-selection and prompt pages; this guide only notes that they are not part of the retry budget. cli.attemptsandtranslator.post_check_max_retry_attemptsare two independent retry budgets: the former covers request sending, the latter covers post-translation checks. They do not replace each other.
Set it in the desktop app
Configure retry and error handling in Settings
- Open “Settings” and select the “General” group.
- Enter an integer in “Retry Attempts”:
-1means unlimited retries,0means no retry after the first failure, and a positive integer is the number of extra retries. - Turning on “Ignore Errors” marks a failed image or batch and continues with the remaining images; turning it off makes any stage exception interrupt the whole task.
Configure request pacing in Settings
- In “Settings”, select the “Translation” group.
- Enter a non-negative integer in “Max Requests Per Minute”:
0means no limit, and a positive integer is the maximum number of requests per minute.
Post-translation quality check options
The current desktop settings layout does not include the post-translation check toggle or its threshold rows in the “Translation” group; these parameters are read by the backend configuration and take effect only through CLI/JSON configuration, so they must not be described as visible UI controls.
Parameters and options
For how each parameter's UI name, storage key, and default value map to each other, see UI Options Reference.
Retry Attempts
“Retry Attempts” is an integer input in the General group that sets how many times a translation request is retried after failure: -1 means unlimited retries, 0 means no retry after the first failure, and a positive integer is the number of extra retries. See CLI, Batch, and Output for details.
Max Requests Per Minute
- Control: integer input.
- Location: Settings → Translation.
- Options: non-negative integer;
0means no limit. - Default:
0. - Mechanism: a positive value is the maximum number of requests per minute; consecutive requests are spaced at least
60 / rpmseconds apart, and retries re-enter the pacing check. It is a request-rate cap only and does not handle 429 automatically.
Ignore Errors
“Ignore Errors” is a toggle in the General group: when enabled, a failed image or batch is marked and processing continues with the remaining images; when disabled, any stage exception interrupts the whole task. See CLI, Batch, and Output for details.
Enable Post-Translation Check
- Control: no UI control (the current desktop settings layout does not bind it; enable it through CLI/JSON configuration).
- Location: backend configuration.
- Options: on or off.
- Default:
false. - Mechanism: when enabled, every text region is checked for repeated-content hallucination, and failed regions are re-translated up to “Max Retry Attempts”; when a batch has more than 10 regions, a batch-level target-language ratio check also runs. If it still fails, the original translation is kept.
Max Retry Attempts
- Control: no UI control (configured through CLI/JSON).
- Location: backend configuration.
- Options: non-negative integer.
- Default:
3. - Mechanism: when a post-translation quality check fails, the region is re-translated and validated again up to this many attempts; if it still fails, the original translation is kept.
Repetition Detection Threshold
- Control: no UI control (configured through CLI/JSON).
- Location: backend configuration.
- Options: positive integer.
- Default:
20. - Mechanism: consecutive character repeats, word/character repeats, and phrase repeats are checked in order; reaching the threshold marks the region as a repetition hallucination and triggers re-translation. A smaller threshold is more sensitive.
Target Language Ratio Threshold
- Control: no UI control (configured through CLI/JSON).
- Location: backend configuration.
- Options: a ratio between
0and1. - Default:
0.5. - Mechanism: when a batch has more than 10 regions, the translations of all regions in the batch are merged and language-detected; if the result is not the target language, the whole batch is re-translated up to “Max Retry Attempts”.
How translation requests are handled
Retry layers and candidate rotation
cli.attempts is the number of extra retries, not the total number of requests. The same budget is consumed by two nested layers: the candidate-rotation layer retries retryable errors on the same API candidate until the budget runs out or a permanent error occurs, then switches candidates; the content-validation layer retries count mismatches, failed quality checks, missing BR markers, and unexpected finish_reason values. A single translation operation can therefore issue far more than attempts + 1 HTTP requests.
sequenceDiagram
participant T as Translator _translate_batch
participant R as run_with_api_candidates
participant C1 as API candidate 1
participant C2 as API candidate 2
T->>R: send request (attempts from cli.attempts)
loop content-validation retries (count/quality/BR/finish_reason)
T->>T: recreate client, wait ~2s
end
R->>C1: first request
C1-->>R: timeout / 429 / 5xx
R->>R: backoff sleep=min(1.0*n, 3.0)
R->>C1: retry same candidate (within budget)
C1-->>R: still failing
R->>R: record candidate 1 state (failed/cooldown/unavailable)
R->>C2: switch to next candidate
C2-->>R: success
R->>T: return translations
RPM request pacing
When translator.max_requests_per_minute is 0 there is no pacing; for a positive value, consecutive requests are at least 60 / rpm seconds apart. Retries also re-enter the pacing check.
sequenceDiagram
participant T as Translator (OpenAI/Gemini)
participant G as Global timestamp table (per model)
participant API as API service
T->>G: read last request time for this model
alt less than 60/rpm seconds elapsed
T->>T: wait 60/rpm - elapsed
end
T->>API: send request (including candidate retries)
API-->>T: response
T->>G: update timestamp for this model
Failure isolation and candidate states
Failure isolation has two layers. At the file/batch layer, cli.ignore_errors decides: when disabled, an exception interrupts the task immediately; when enabled, the current file is marked as failed and processing continues. At the candidate layer, only unavailable and a cooldown that is still active exclude a candidate from the list, while a plain failed state does not exclude it and the candidate can be tried again on the next request.
flowchart TD
A["Process one image / one batch"] --> B{"stage raised an error?"}
B -->|no| C["continue with the next image"]
B -->|yes| D{"ignore_errors enabled?"}
D -->|no| E["raise, interrupt the whole task"]
D -->|yes| F["raise FileTranslationFailure(stage)"]
F --> G["mark the file/batch failed, keep no rollback to source"]
G --> C
The candidate state machine follows. The cooldown duration defaults to 60 seconds, uses the Retry-After header when present, and is capped at 600 seconds; permanent errors (400-class, 402, 404, quota, invalid key) go straight to unavailable and can only be cleared by re-enabling or testing in API Management.
stateDiagram-v2
[*] --> available
available --> failed: non-rate-limit error exhausts retry budget
available --> cooldown: 429 / rate-limit marker
available --> unavailable: permanent error (400-class / quota / 404)
failed --> available: request succeeds
failed --> cooldown: later classified as rate-limited
cooldown --> available: cooldown expires or request succeeds
unavailable --> available: re-enable / test in API Management
Post-translation check flow
The post-translation check runs only when translator.enable_post_translation_check=true, and the current desktop layout does not expose this toggle. The check has two layers: first, each region is checked for repetition hallucination and failing regions are re-translated individually; then, the whole batch is checked for target-language ratio and re-translated as a batch. Both loops are bounded by post_check_max_retry_attempts.
flowchart TD
A["Translation finished"] --> B{"enable_post_translation_check?"}
B -->|no| Z["proceed to mask / inpaint / render"]
B -->|yes| C["region-level repetition-hallucination check"]
C --> D{"any failing regions?"}
D -->|no| F{"batch regions total > 10?"}
D -->|yes| E["re-translate single region and validate again"]
E --> D
F -->|no| Z
F -->|yes| G["batch-level target-language ratio check"]
G --> H{"passed?"}
H -->|yes| Z
H -->|no| I["re-translate the whole batch and re-check"]
I --> J{"retries ≤ post_check_max_retry_attempts?"}
J -->|yes| G
J -->|no| K["keep original translation"]
K --> Z
Models, network, and quality
cli.attempts,translator.max_requests_per_minute,cli.ignore_errors, and the post-translation check are four independent dimensions: retry budget, request pacing, failure isolation, and quality checking do not replace each other.attempts=-1combined with content filters or persistent 5xx responses may run for a long time;max_requests_per_minuteonly throttles sending and does not reduce the cost of a single request.ignore_errorsis file/batch-level isolation; a single failing region inside a page still goes through quality retries or keeps its original translation and is not affected by this toggle.- Candidate rotation only matters when more than one API candidate exists; with a single candidate,
cli.attemptsdecides the retry budget on it. Candidate state is kept in the process across tasks and is not written to configuration files. save_quality(Image Save Quality) andcontext_size(Context Pages) also affect the perceived “quality”, but they are output compression quality and context quality respectively; see CLI batch and output and Context and prompts.
