Behind the new `OPENCODE_TRANSIENT_FAILOVER_BACKOFF` flag (default off), after two consecutive transient upstream failures the opencode rotation pauses before each later account (1.5s, 3s, 6s, capped at 10s per request) instead of hammering the upstream.
Maintainer rework before merge (kept the idea, no default behavior change):
- The pause honors the client abort signal (no dispatch after a disconnect), the failed attempt's body is cancelled before sleeping, `transientRetryDelayMs` now uses its arguments, and the sleep is injectable so the tests run without real timers.
Validated first on the combined board of all 38 PRs of this batch (10 merged as-is, 28 after the maintainer rework) on top of release/v3.8.51 c0f92ec: typecheck:core, check:open-sse-typecheck and check:dashboard-typecheck clean; ESLint clean on every changed file; file-size (rebaselined for the combined growth), complexity, cognitive-complexity, changelog-integrity, docs-counts, docs-sync, migration-numbering and i18n new-key gates green; 735 focused node:test cases with the only batch-caused failure (a flag-count assertion) fixed. Then re-validated alone on the fresh release tip right before this merge: ESLint on the changed files, typecheck:core, check:open-sse-typecheck, the file-size/complexity/changelog gates and this PR's own tests.
Thanks @maxmad64bis!
41 KiB
title, version, lastUpdated
| title | version | lastUpdated |
|---|---|---|
| Feature Flags | 3.8.51 | 2026-09-03 |
Feature Flags
Runtime toggles that change OmniRoute's behavior without a redeploy. Every flag listed here is defined in
src/shared/constants/featureFlagDefinitions.ts— the single source of truth. The dashboard and the REST API both read from that file, so the table below is generated to match it 1:1.
What Feature Flags Are
A feature flag is a named toggle (boolean or enum) whose value can be changed at
runtime and persisted in the database, with no process redeploy required. Each
flag is described by a FeatureFlagDefinition with a key, label,
description, category, defaultValue, type, and a requiresRestart hint.
Resolution Order
The effective value of a flag is resolved by
resolveFeatureFlag() with this
precedence (highest wins):
- DB override — a value stored in the
key_valuetable under thefeature_flagsnamespace (set via the dashboard or the REST API). - Environment variable —
process.env[<KEY>], if set and non-empty. - Definition default — the
defaultValuefromfeatureFlagDefinitions.ts.
A boolean flag is considered enabled when its effective value is "true",
"1", or "yes" (see isFeatureFlagEnabled()).
Note
Most flags also have a matching environment variable of the same name documented in
ENVIRONMENT.md. The flag's DB override takes precedence over that environment variable. A flag withrequiresRestart: trueis persisted immediately but only re-read at process startup — toggling it surfaces a "Restart Server" banner in the dashboard.
Flag Catalog
67 flags across 6 categories. Default is the definition default — the value used when neither a DB override nor an environment variable is present.
Security (10)
| Key | Type | Default | Description |
|---|---|---|---|
REQUIRE_API_KEY |
boolean | false |
Require an API key for all incoming requests. |
INPUT_SANITIZER_ENABLED |
boolean | true |
Enable input sanitization for all requests. |
INJECTION_GUARD_MODE |
enum | off |
Prompt injection guard mode. Values: off, warn, block, redact. |
PII_REDACTION_ENABLED |
boolean | false |
Redact PII from requests (independent of INPUT_SANITIZER_MODE). |
PII_RESPONSE_SANITIZATION |
boolean | false |
Sanitize PII from provider responses. |
PII_RESPONSE_SANITIZATION_MODE |
enum | redact |
Mode for PII response sanitization. Values: redact, warn, block, off. |
OUTBOUND_SSRF_GUARD_ENABLED |
boolean | true |
Block outbound requests to private/internal IP ranges. |
ALLOW_API_KEY_REVEAL |
boolean | false |
Allow authenticated dashboard users to reveal stored API keys instead of only seeing masked values. |
AUTH_LOG_INCLUDE_ACCOUNT_ID |
boolean | false |
Include account prefix in AUTH log lines (e.g. "Using account: abc12345..."). Disabled by default so account identifiers are redacted from shared/multi-tenant process logs. Independent from Debug Mode; flipping Debug Mode does not reveal this. |
OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN |
boolean | false |
When OIDC is enabled, disable password login so users can only authenticate via OIDC Single Sign-On. When disabled (default), both password login and OIDC are available. |
Network (14)
| Key | Type | Default | Restart | Description |
|---|---|---|---|---|
ENABLE_TLS_FINGERPRINT |
boolean | false |
✓ | Enable TLS fingerprint stealth mode. |
AUDIO_REMOTE_PROVIDER_NODES |
boolean | false |
Allow the /v1/audio/* routes to use OpenAI-compatible provider nodes hosted outside localhost. Off by default — routing audio to a remote host changes egress identity and must be an explicit operator decision. Loopback nodes are always allowed and unaffected. | |
PROXY_AUTO_SELECT_ENABLED |
boolean | false |
When no proxy is assigned to a connection, auto-select the first working proxy from the registry. Off by default (otherwise any registry proxy becomes a global fallback — #3332). | |
OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK |
boolean | false |
Allow OAuth and provider validation flows to bypass a pinned proxy and connect directly when proxy reachability pre-checks fail. Off by default because this can change egress IP. | |
NETWORK_ROTATION_SHARED_EGRESS_GUARD |
boolean | true |
On a network exception (timeout, connection refused/reset) for a multi-account rotation executor, when the failing account has no dedicated proxy, apply a short cooldown and skip other proxy-less accounts for the rest of the request instead of retrying each one. On by default (safe: no egress IP change, only reduces latency/cooldown risk on shared-egress accounts). Disable to restore immediate propagation on the first proxy-less throw. | |
PROXY_SKIP_RECENTLY_FAILED |
boolean | false |
Proxy pools and the per-account rotation of opencode stop re-serving a proxy that just failed (refused TCP probe, or a 429 received through it) for a per-process period that doubles on each repeat, up to a cap. No proxy status is written; with every candidate set aside the choice is unchanged. Off by default. | |
PROXY_POOL_EGRESS_OBSERVATION |
boolean | false |
Show, under a proxy pool in the dashboard, how many observed egress IPs served its members over the last 24 h and how many connections used them. Read-only, computed from the proxy log, never used for routing. Off by default. | |
OPENCODE_RESPONSES_STALL_ROTATION |
boolean | false |
For the OpenCode executor, watch the first body byte of a streamed Responses reply (window: RESPONSES_FIRST_BYTE_TIMEOUT_MS, default 15000). A 2xx Responses stream that stays silent past the window is treated as stalled: the account is cooled down and the request rotates to the next account once; a second stall fails fast. Off by default: stalled streams keep today's wait until the stream readiness timeout. |
|
OPENCODE_USER_BLOCKED_ROTATION |
boolean | false |
OpenCode executor: on a 403/451 carrying a user_blocked refusal (not geo, not a Cloudflare fingerprint rejection), cool the refused account down and rotate to the next account at most once per request; a second refusal is returned as-is, without a success mark. Off by default: routing around an upstream user block can look like evasion and spread the flag across the fleet. |
|
OPENCODE_TRANSIENT_FAILOVER_BACKOFF |
boolean | false |
OpenCode rotation: after two consecutive transient upstream failures (5xx or an empty 400), pause before the next account — 1.5s doubling per further failure, capped at 6s per pause and 10s per request, skipped on client disconnect; the failed body is released before waiting. Off by default: failover stays immediate. | |
MITM_DISABLE_TLS_VERIFY |
boolean | false |
✓ | Disable TLS certificate verification for the MITM proxy. Danger. |
OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS |
boolean | false |
Allow provider URLs pointing to private/internal networks. | |
OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS |
boolean | true |
Allow adding/validating providers on local/private addresses (127.0.0.1, localhost, LAN). On by default (local-first); disable for strict public-only blocking. Cloud-metadata stays blocked. | |
ENABLE_CC_COMPATIBLE_PROVIDER |
boolean | false |
✓ | Enable Claude Code compatible provider mode. |
Policies (5)
| Key | Type | Default | Description |
|---|---|---|---|
TOOL_POLICY_MODE |
enum | disabled |
Tool-use policy enforcement mode. Values: disabled, warn, block. |
RATE_LIMIT_AUTO_ENABLE |
boolean | false |
Automatically enable rate limiting based on usage patterns. |
DISABLE_CONTEXT_WINDOW_CHECKS |
boolean | false |
Skip OmniRoute's local context-window / max-input-token check for direct single-model requests. Upstream limits still apply. |
CAPABILITY_FILTER_ENABLED |
boolean | false |
Reject requests before dispatch when the target model lacks required capabilities (vision, tools, structured output, context window). Protects direct single-provider requests that bypass the combo-layer compatibility filter. |
RADAR_ENABLED |
boolean | false |
Enable the OmniRoute Radar module (catalog feed screens and sync). Off by default; enabling only unlocks the UI — data sync remains a separate opt-in. |
Runtime (29)
| Key | Type | Default | Restart | Description |
|---|---|---|---|---|
UNIVERSAL_CONTEXT_HANDOFF_ENABLED |
boolean | true |
Generate and inject conversation summaries when combo routing switches models. Disable to treat model switches independently and prevent background handoff requests for all existing and future combos. | |
RESPONSES_PASSTHROUGH_DROP_COMMENTARY |
boolean | true |
Drop internal commentary-phase output items from Responses API passthrough streams before forwarding to clients. Disable to receive raw upstream commentary. | |
OMNIROUTE_MCP_ENFORCE_SCOPES |
boolean | true |
Enforce scope restrictions on MCP tool access. | |
OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS |
boolean | false |
Compress MCP tool descriptions to reduce token usage. | |
OMNIROUTE_ENABLE_RUNTIME_BACKGROUND_TASKS |
boolean | false |
Enable background task processing at runtime. | |
OMNIROUTE_DISABLE_BACKGROUND_SERVICES |
boolean | false |
✓ | Disable all background services (quota refresh, sync, etc). |
OMNIROUTE_RTK_TRUST_PROJECT_FILTERS |
boolean | false |
Trust project-level RTK filters without validation. | |
OMNIROUTE_ENABLE_LIVE_WS |
boolean | true |
✓ | Start the real-time dashboard WebSocket server on import (port 20132 by default). |
OMNIROUTE_CODEX_WS_ENABLED |
boolean | true |
Allow Codex to use the Responses-over-WebSocket transport. When off, Codex falls back to HTTP Responses. | |
OMNIROUTE_CODEX_APP_SERVER_ENABLED |
boolean | true |
Allow Codex to use the local app-server WebSocket JSON-RPC transport (codexTransport=app-server). When off, connections opted into app-server fall back to Codex's other transports. | |
OMNIROUTE_EMERGENCY_FALLBACK |
boolean | true |
Route budget-exhausted requests to the emergency free fallback provider/model. (See Emergency Budget Fallback below.) | |
STREAM_RECOVERY_ENABLED |
boolean | false |
Enable transparent early retry for truncated upstream SSE streams before any response bytes reach the client. | |
STREAM_RECOVERY_MIDSTREAM_ENABLED |
boolean | false |
Allow stream recovery to re-request and stitch a response after bytes have already reached the client. | |
STREAM_RECOVERY_TOOLCALL_ORDER_FIX |
boolean | false |
Make mid-stream continuation tool-call safe: never resume a cut stream once a tool call was emitted (in flight or already finished with finish_reason tool_calls), and close after one empty continuation instead of spending the whole budget. Off: release behavior. | |
STREAM_EARLY_EOF_SIBLING_FAILOVER_ENABLED |
boolean | false |
Fail over once to a sibling connection when an SSE stream closes before emitting any useful frame and the bounded same-connection retry is spent; with no usable sibling the original STREAM_EARLY_EOF 502 is returned. Off by default: early-EOF stays terminal after the same-connection retry. |
|
MODEL_CATALOG_INCLUDE_NAMES |
boolean | true |
Include display-friendly name fields in /v1/models responses. Disable for clients that expect model IDs only. |
|
MODELS_CATALOG_PREFIX_MODE |
enum | dual |
Controls how model IDs are prefixed in /v1/models. 'dual' (default) emits both alias and canonical provider-id prefixes for backward compatibility. 'alias' emits only the short alias prefix (e.g. ds-web/model, not deepseek-web/model). 'canonical' emits only the full provider-id prefix. Values: dual, alias, canonical. |
|
ARENA_ELO_SYNC_ENABLED |
boolean | true |
Enable periodic Arena AI leaderboard ELO sync for model intelligence rankings. | |
EXPOSE_CC_DISCOVERY_ALIASES |
boolean | false |
Advertise claude/<provider>/<model> mirror ids on /v1/models so Claude Code gateway model discovery lists non-Claude models. Global level of the three-level gate (env wins over the dashboard override). See Claude Code configuration. |
|
NO_THINKING_ALIAS_ENABLED |
boolean | true |
Master switch for the no-think// gateway aliases. On (default): /v1/models advertises a no-thinking variant for every eligible thinking-capable Claude model, and a no-think/ id sent on a request resolves back to the real model with reasoning suppressed. Off: no variants are advertised and a no-think/ id is treated like any other unknown model id. The per-model ModelSpec.noThinkingAlias opt-in/opt-out still applies while this is on. | |
OMNIROUTE_DISABLE_THINKING_LEVEL_VARIANTS |
boolean | false |
Disable the generation of thinking level variants (e.g. -low, -medium, -high) in the /v1/models catalog. | |
OMNIROUTE_CHAT_VIRTUAL_LANES |
boolean | false |
✓ | Enable per-tenant adaptive virtual admission lanes for provider dispatch (#9654): one tenant's burst no longer 503s another. The OMNIROUTE_CHAT_VIRTUAL_LANES env var wins over this dashboard override; changes take effect at server restart. |
EXPOSE_FUNCTIONAL_GATEWAY_MIRRORS |
boolean | false |
Advertise / mirror ids on /v1/models for models whose canonical owner has no active credential but a passthrough gateway with an active credential routes them. Warning: adds catalog entries for all clients when enabled globally. | |
NEWAPI_AGGREGATOR_BALANCE |
boolean | false |
Enable balance detection for New-API / One-API / Sub2API aggregator compatible nodes. When enabled, compatible nodes with the aggregator flag set will report their balance in the dashboard and quota-preflight routing. | |
SERVER_OWNED_TOOL_LOOP_ENABLED |
boolean | false |
Continue non-streaming server-owned tool calls until the model returns a client-usable response. | |
SEARCH_STATS_HIDE_DELETED_CONNECTIONS |
boolean | false |
Search stats and recent searches only count providers that still have a live connection (keyless providers such as duckduckgo-free always count). Off keeps every retained search row with a provider id. | |
FREE_BADGE_REQUIRES_PROVIDER_FREE_TIER |
boolean | false |
Dashboard provider pages: show the Free badge only on signals the provider honors — drops the display-name heuristic, non-boolean free fields and :free suffixes on registered providers without a documented free tier. Off keeps the historical badge rule. | |
RETRY_AFTER_PROVENANCE_ENABLED |
boolean | false |
On aggregated 429/503 unavailable responses, omit Retry-After when no concrete future retry time is known (instead of a synthetic 1s), add error.retry_after_provenance (signal | none), and let combo drain paths read prose retry hints from JSON and plain-text upstream bodies. The field only appears on responses built by unavailableResponse(); other 429/503 bodies are unchanged. |
|
PROTECTED_PRIORITY_INFRA_502_ENABLED |
boolean | false |
When a priority combo target marked fallback-only-on-quota-exhaustion stops the combo for a cause that is provably not quota (provider circuit breaker open, predictive latency skip), answer 502 instead of the quota-looking 503. Lockout, cooldown, unavailable, exhaustion and concurrency-cap stops keep 503. |
CLI (5)
| Key | Type | Default | Restart | Description |
|---|---|---|---|---|
CLI_COMPAT_ALL |
boolean | false |
✓ | Enable compatibility mode for all CLI clients. |
MODEL_ALIAS_COMPAT_ENABLED |
boolean | false |
Enable model alias compatibility layer. | |
PRICING_SYNC_ENABLED |
boolean | false |
Enable automatic pricing data synchronization (also requires the PRICING_SYNC_ENABLED environment variable). |
|
OMNIROUTE_AUTO_SYNC_CODEX_PROFILES |
boolean | false |
After a provider model sync, automatically (re)write ~/.codex/*.config.toml profile files from the live catalog. Never changes the active/default Codex config. Off by default. | |
OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES |
boolean | false |
After a provider model sync, automatically (re)write ~/.claude/profiles//settings.json Claude Code profiles from the live catalog. Never changes the active/default Claude config. Off by default. |
Health (4)
| Key | Type | Default | Description |
|---|---|---|---|
OMNIROUTE_DISABLE_LOCAL_HEALTHCHECK |
boolean | false |
Disable the local instance health check endpoint. |
OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK |
boolean | false |
Disable the token validation health check. |
SKILLS_SANDBOX_NETWORK_ENABLED |
boolean | false |
Enable network access in the skills sandbox environment. |
PROXY_HEALTH_BLOCKED_RESETS_STREAK |
boolean | false |
In the proxy health sweep, a probe the target refused (401/403/429) resets the proxy's consecutive-failure streak. Off by default: a refusal stays neutral (#10654). A 5xx stays inconclusive either way; a refusal never removes, disables or re-activates a proxy. |
Note
INPUT_SANITIZER_BLOCK_THRESHOLDand its legacy aliasINJECTION_GUARD_BLOCK_THRESHOLDtune theblockmode ofINJECTION_GUARD_MODE, but they are plain environment variables read bysrc/shared/utils/injectionSeverity.ts, not feature flags: they have no DB override and no dashboard toggle. SeeENVIRONMENT.md.
Note
The
Restartcolumn marks flags withrequiresRestart: true— the value is persisted instantly but only takes effect after the process reloads. Enum flags reject any value outside their allowed set (validated server-side in bothsetFeatureFlagOverride()and the RESTPUThandler).
Toggling Flags
Dashboard
Navigate to Dashboard → Settings → Feature Flags
(/dashboard/settings/feature-flags). The grid
(src/app/(dashboard)/dashboard/settings/components/FeatureFlagsGrid.tsx)
supports:
- Search by key or description, and filter by category (plus a synthetic Requires Restart view).
- A toggle for boolean flags and a dropdown for enum flags
(
src/app/(dashboard)/dashboard/settings/components/FeatureFlagCard.tsx). - A source badge per flag —
DB,ENV, orDEF— showing where the effective value came from. - A Reset button (shown only for
DB-sourced flags) to drop the override, and a Reset All Overrides button at the bottom. - A Restart Server banner when a
requiresRestartflag is changed.
REST API
All operations go through a single route:
src/app/api/settings/feature-flags/route.ts.
Every method requires an authenticated dashboard session (401 otherwise).
GET /api/settings/feature-flags
Returns every flag with its effective value, source, and a summary.
{
"flags": [
{
"key": "REQUIRE_API_KEY",
"label": "Require API Key",
"description": "Require an API key for all incoming requests",
"category": "security",
"type": "boolean",
"enumValues": null,
"defaultValue": "false",
"effectiveValue": "false",
"source": "default", // "db" | "env" | "default"
"requiresRestart": false,
"warningLevel": "caution",
},
// ... all 67 flags
],
"summary": {
"total": 56,
"active": 0,
"inactive": 0,
"overriddenByDb": 0,
"overriddenByEnv": 0,
},
}
PUT /api/settings/feature-flags
Set or remove a single override. Body: { key: string; value?: string }.
Omitting value removes the override (restoring env / default).
# Set a DB override
curl -X PUT http://localhost:20128/api/settings/feature-flags \
-H "Content-Type: application/json" \
-d '{"key":"REQUIRE_API_KEY","value":"true"}'
# Remove the override (no "value")
curl -X PUT http://localhost:20128/api/settings/feature-flags \
-H "Content-Type: application/json" \
-d '{"key":"REQUIRE_API_KEY"}'
The response echoes the new effectiveValue/source, the previousValue/
previousSource, and requiresRestart. Unknown keys and out-of-range enum
values are rejected with 400.
DELETE /api/settings/feature-flags
Clears all DB overrides at once, restoring every flag to its env / default
value. Returns { cleared: <count>, message: "..." }.
Note
Flags with
requiresRestart: trueonly take effect after a process reload. The dashboard's restart flow callsPOST /api/restartand then pollsGET /api/health/pinguntil the server is back up.
Emergency Budget Fallback
OMNIROUTE_EMERGENCY_FALLBACK (category runtime, default true) controls the
emergency free-fallback path in
open-sse/services/emergencyFallback.ts.
When enabled, requests that exhaust their budget are routed to a free fallback
provider/model instead of failing outright. Set it to false (or 0) — via the
dashboard toggle, a DB override, or the OMNIROUTE_EMERGENCY_FALLBACK
environment variable — to disable the behavior and let budget-exhausted requests
fail. (Surfaced as a dashboard toggle in PRs #3741 / #3752.)
See Also
- Environment Variables Reference — most flags have a same-named environment variable documented there (the DB override takes precedence over it).
src/shared/constants/featureFlagDefinitions.ts— source of truth for every flag.src/shared/utils/featureFlags.ts— resolution logic (resolveFeatureFlag,isFeatureFlagEnabled,resolveAllFeatureFlags).src/lib/db/featureFlags.ts— DB override persistence in thefeature_flagsnamespace of thekey_valuetable.