angular/angular · warning

When merging multiple translation files, the target locale "

Error message

When merging multiple translation files, the target locale "${nextBundle.locale}" found in "${filePaths[i]}" does not match the target locale "${bundle.locale}" found in earlier files [${previousFiles}].

What it means

`mergeBundles()` loads every listed translation file and folds them into one bundle; when a later file declares a target locale different from the first file's, this warning is emitted (only if a diagnostics object is attached to the loader). The merge continues, the first bundle's locale wins, and duplicate message IDs across the files are separately reported.

Source

Thrown at packages/localize/tools/src/translate/translation_files/translation_loader.ts:141

  /**
   * There is more than one `filePath` for this locale, so load each as a bundle and then merge
   * them all together.
   */
  private mergeBundles(
    filePaths: AbsoluteFsPath[],
    providedLocale: string | undefined,
  ): TranslationBundle {
    const bundles = filePaths.map((filePath) => this.loadBundle(filePath, providedLocale));
    const bundle = bundles[0];
    for (let i = 1; i < bundles.length; i++) {
      const nextBundle = bundles[i];
      if (nextBundle.locale !== bundle.locale) {
        if (this.diagnostics) {
          const previousFiles = filePaths
            .slice(0, i)
            .map((f) => `"${f}"`)
            .join(', ');
          this.diagnostics.warn(
            `When merging multiple translation files, the target locale "${nextBundle.locale}" found in "${filePaths[i]}" does not match the target locale "${bundle.locale}" found in earlier files [${previousFiles}].`,
          );
        }
      }
      Object.keys(nextBundle.translations).forEach((messageId) => {
        if (bundle.translations[messageId] !== undefined) {
          this.diagnostics?.add(
            this.duplicateTranslation,
            `Duplicate translations for message "${messageId}" when merging "${filePaths[i]}".`,
          );
        } else {
          bundle.translations[messageId] = nextBundle.translations[messageId];
        }
      });
    }
    return bundle;
  }
}

View on GitHub (pinned to 51cb07e980)

Solutions

  1. Group translation file paths by locale and call the translate step (mergeBundles) once per locale.
  2. Find the offending file named in the warning and fix its declared locale to match the rest of the set.
  3. Add a CI check that every file in a merge set declares the same locale before invoking the loader.

Example fix

// before: merging files that declare different locales
const bundle = loader.mergeBundles(['fr.json', 'en-US.json']);

// after: one merge per locale
const fr = loader.mergeBundles(['fr.json', 'fr-FR.json']);
const en = loader.mergeBundles(['en.json', 'en-US.json']);
Defensive patterns

Strategy: validation

Validate before calling

// Group translation files by declared locale before merging
function groupByLocale(files: string[]): Map<string, string[]> {
  const groups = new Map<string, string[]>();
  for (const f of files) {
    const declared = JSON.parse(readFileSync(f, 'utf8'))['@@locale'] ?? JSON.parse(readFileSync(f, 'utf8')).locale;
    groups.set(declared, [...(groups.get(declared) ?? []), f]);
  }
  return groups; // merge each group separately
}

Prevention

When it happens

Trigger: Calling `mergeBundles(['fr.json', 'en.json'])` - any list where files parsed to different `locale` values; the warning fires at the first index whose locale differs from bundle[0].

Common situations: Globbing all translation files (multiple locales) into a single translate/build invocation instead of grouping per locale; one stray file with a wrong or missing locale field mixed into a per-locale set.

Related errors


AI-assisted analysis of angular/angular@51cb07e980 (2026-08-22). Data as JSON: /api/errors/5b4a64bb82a83480. Report an issue: GitHub.