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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions