marktext/marktext · error · Error

Translation file not found for language: ${language}

Error message

Translation file not found for language: ${language}

What it means

Thrown by loadTranslations() when the resolved locale JSON path does not exist on disk. In dev/PERF_TESTING the resolver prefers ${language}.min.json and falls back to ${language}.json under <cwd>/static/locales; in production it reads process.resourcesPath/static/locales/${language}.min.json. The function catches its own throw and retries with 'en', so this only surfaces to callers (returns null) if the English file itself is missing.

Source

Thrown at packages/desktop/src/common/i18n.ts:36

    return translationsCache[language]
  }

  try {
    // Used in both main and preload processes, so we can't lean on
    // `global.__static`, which is main-only.
    // In development, prefer the pre-minified file when present, but fall back
    // to the raw .json so `pnpm run dev` works without running minify-locales.
    let localePath: string
    if (process.env.NODE_ENV === 'development' || process.env.PERF_TESTING === 'true') {
      const minPath = path.join(process.cwd(), 'static', 'locales', `${language}.min.json`)
      const rawPath = path.join(process.cwd(), 'static', 'locales', `${language}.json`)
      localePath = fs.existsSync(minPath) ? minPath : rawPath
    } else {
      localePath = path.join(process.resourcesPath, 'static', 'locales', `${language}.min.json`)
    }

    if (!fs.existsSync(localePath)) {
      throw new Error(`Translation file not found for language: ${language}`)
    }

    const content = fs.readFileSync(localePath, 'utf8')

    const translationData: Translations = JSON.parse(content)

    translationsCache[language] = translationData
    return translationData
  } catch (error) {
    console.error('Error loading translation:', error)
    if (language !== 'en') {
      return loadTranslations('en')
    }
    return null
  }
}

/**

View on GitHub (pinned to e52106fd1c)

Solutions

  1. Run dev from the repo root via `pnpm run dev` (the workspace proxy sets cwd to packages/desktop) so process.cwd()/static/locales resolves.
  2. For production builds, ensure `pnpm run minify-locales` runs before packaging (it is wired into build:win/mac/linux but not dev).
  3. Validate the language against getSupportedLanguages()/isLanguageSupported() before passing it to loadTranslations.
  4. If adding a new language, place both the raw ${code}.json and minified ${code}.min.json in packages/desktop/static/locales/.

Example fix

// before
loadTranslations(userLang)
// after
import { isLanguageSupported } from 'common/i18n'
const lang = isLanguageSupported(userLang) ? userLang : 'en'
loadTranslations(lang)
Defensive patterns

Strategy: validation

Validate before calling

import { isLanguageSupported } from 'common/i18n'
function safeLang(lang: string): string {
  return isLanguageSupported(lang) ? lang : 'en'
}
// then: loadTranslations(safeLang(userLang))

Type guard

function isValidLanguage(lang: string): lang is import('common/i18n').SupportedLanguage {
  return ['en','zh-CN','zh-TW','es','fr','de','ja','ko','pt','tr'].includes(lang)
}

Try / catch

// loadTranslations already self-recurses to 'en' on error and returns null;
// callers should treat null as 'use key as fallback':
const t = getTranslation(key, lang) // returns key if translations null

Prevention

When it happens

Trigger: Calling loadTranslations with a language code that has no matching locale file; running `pnpm run dev` from a directory other than packages/desktop (process.cwd() resolves static/locales relative to cwd); a production build where minify-locales was skipped so ${language}.min.json is absent; a language string outside SUPPORTED_LANGUAGES passed straight through.

Common situations: Developers running the renderer/preload from the repo root instead of packages/desktop hit the wrong cwd. Production packages built without `pnpm run minify-locales` lack the .min.json files. A stale preference.json referencing a removed language code triggers it on startup.

Related errors


AI-assisted analysis of marktext/marktext@e52106fd1c (2026-08-12). Data as JSON: /api/errors/53c083a9dd573541. Report an issue: GitHub.