siyuan-note/siyuan · error · Error

Unable to load English commands: ${response.status}

Error message

Unable to load English commands: ${response.status}

What it means

requestEnglishCommandTranslations fetches `/appearance/langs/en.json` (with cache: no-store) to load English command translation strings. If the HTTP response status is not ok (4xx/5xx), it throws this error embedding the status code. The message text says 'English commands' but the fetched resource is the English i18n language file used to translate command labels.

Source

Thrown at app/src/command/english.ts:12

let englishLanguages: Record<string, string> | undefined;
let englishLanguagesPromise: Promise<Record<string, string> | undefined> | undefined;

export const getEnglishCommandLabel = (key: string) => englishLanguages?.[key];

export const requestEnglishCommandTranslations = async (
    version: string,
    fetcher: typeof fetch = fetch,
) => {
    const response = await fetcher(`/appearance/langs/en.json?v=${version}`, {cache: "no-store"});
    if (!response.ok) {
        throw new Error(`Unable to load English commands: ${response.status}`);
    }
    return response.json() as Promise<Record<string, string>>;
};

export const initializeEnglishCommandTranslations = (
    currentLanguage: string,
    currentLanguages: Record<string, string>,
    version: string,
) => {
    if (currentLanguage === "en") {
        englishLanguages = currentLanguages;
        return Promise.resolve(englishLanguages);
    }
    if (!englishLanguagesPromise) {
        englishLanguagesPromise = requestEnglishCommandTranslations(version)
            .then(languages => {
                englishLanguages = languages;
                return languages;

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Verify app/appearance/langs/en.json exists in the running instance by opening /appearance/langs/en.json in the browser or curl -I
  2. If 404, restore the missing file (reinstall/repackage the app or restore the appearance directory from the repository)
  3. If 403/500, check kernel logs and file permissions on the appearance directory
  4. Add a fallback so a failed load degrades gracefully (use raw command names) instead of failing initialization

Example fix

// before
const response = await fetcher(`/appearance/langs/en.json?v=${version}`, {cache: "no-store"});
if (!response.ok) {
    throw new Error(`Unable to load English commands: ${response.status}`);
}
// after
const response = await fetcher(`/appearance/langs/en.json?v=${version}`, {cache: "no-store"});
if (!response.ok) {
    console.warn(`English command translations unavailable (HTTP ${response.status}), using fallback`);
    return {};
}
Defensive patterns

Strategy: fallback

Try / catch

let translations: Record<string, string> = {};
try {
    translations = await requestEnglishCommandTranslations(version);
} catch (e) {
    console.warn("English i18n load failed, using keys as-is:", e);
}

Prevention

When it happens

Trigger: initializeEnglishCommandTranslations calls requestEnglishCommandTranslations(version) and the fetch of `/appearance/langs/en.json?v=<version>` returns a non-2xx status — e.g. the kernel serves 404 because the file is missing, or 500 on a server error.

Common situations: Deployments where app/appearance/langs/en.json was not packaged or was deleted; the workspace's appearance directory misconfigured; a proxy/static server returning 404 for the query-string URL; kernel not fully booted when the frontend requests the file; after an upgrade where appearance assets are stale.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/6493322cb5198d9c. Report an issue: GitHub.