Skip to content

/api/ui-config ignores Accept-Language ordering and q-values — returns zh if Chinese appears anywhere in the list #1829

Description

@cardin

Version

codebase-memory-mcp 0.10.8

Platform

Windows (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

ui

What happened, and what did you expect?

Summary

The UI language selection in the web dashboard (http://localhost:9749/) does not respect the user's preferred language. The /api/ui-config endpoint returns "lang":"zh" whenever any Chinese tag appears anywhere in the Accept-Language header, regardless of position or quality values. As a result, any user with a bilingual browser language list (e.g. English (United States) first, Chinese third) gets the Chinese UI even though English is their top preference.

Impact

For a site, per RFC 9110, the server should use the highest-preference language it supports. In practice:

  • Bilingual users (very common, e.g. en-US + zh-CN in Edge/Chrome language lists) always get the Chinese UI, which most of them did not opt into.
  • The only current workaround is removing the secondary language from the browser's preferred-language list entirely — which breaks other sites that legitimately want the user's full preference list.

Notably, the frontend already implements the correct logic

The UI bundle's own fallback path (used when the /api/ui-config fetch fails) parses the Accept-Language-style string properly:

function JT(i, e) {
  if (e === "zh" || e === "en") return e;
  if (!i) return "en";
  const t = i.split(",").map(n => {
    const [r, ...o] = n.trim().split(";");
    const u = o.map(d => /^\s*q\s*=\s*([\d.]+)\s*$/i.exec(d)).find(Boolean);
    return { tag: r.trim().toLowerCase(), q: u ? Number(u[1]) : 1 };
  })
  .filter(({tag: n, q: r}) => n && Number.isFinite(r) && r > 0)
  .sort((a, b) => b.q - a.q)          // sort by q-value
  .find(({tag: n}) => n.split("-")[0] === "zh" || n.split("-")[0] === "en");
  return t != null && t.tag.startsWith("zh") ? "zh" : "en";
}

The server-side parser could reuse the same approach: parse each tag with its q-value (default 1.0), sort descending, and return the first tag whose base language is zh or en.

Suggested fix

  1. Server (primary): parse the Accept-Language header per RFC 9110 — split into weights, sort by weight descending, return "zh" only if the highest-preference matched tag is Chinese. (Or, more simply: return the first zh/en tag in the list's given order, since browsers already sort by preference.)
  2. Optional (feature): a way to pin the UI language so bilingual users don't have to manage their browser's language list per-site — e.g. a CBM_UI_LANG env var (default: auto = header-based) or a persisted lang override in the UI itself.

Environment

  • Windows 11/10, daemon installed via the official install.ps1 (binary date: 2026-08-25; no embedded version metadata)
  • Browser: Microsoft Edge (Chromium). Same behavior would apply to any browser whose Accept-Language contains a Chinese tag after English.

Current workaround

Remove the secondary (Chinese) language from the browser's preferred-languages list, or use a browser profile with an English-only language list.

Reproduction

With the daemon running (default port 9749):

# Top preference is English (q=0.95), Chinese is secondary (q=0.5):
curl -H "Accept-Language: en-US;q=0.95,zh-CN;q=0.5" http://localhost:9749/api/ui-config
# => {"lang":"zh", ...}   ❌ expected "en"

# Plain ordering, en first:
curl -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8" http://localhost:9749/api/ui-config
# => {"lang":"zh", ...}   ❌ expected "en"

# Chinese genuinely preferred:
curl -H "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8" http://localhost:9749/api/ui-config
# => {"lang":"zh", ...}   ✅

# English only:
curl -H "Accept-Language: en-US,en;q=0.9" http://localhost:9749/api/ui-config
# => {"lang":"en", ...}   ✅

The effective behavior is if (list contains a zh tag) return "zh"; else return "en"; — order and q values are not considered.

Logs


Diagnostics trajectory (memory / performance / leak issues)


Project scale (if relevant)

No response

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.ux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions