arduino/Arduino · error · RuntimeError

Two or more candidates for %s: %s

Error message

Two or more candidates for %s: %s

What it means

canonical_lang maps a base language code (e.g. 'en') to an exact entry in the Transifex project language list. If more than one entry shares the same base prefix before '_', the mapping is ambiguous and a RuntimeError is raised listing all candidates.

Source

Thrown at arduino-core/src/processing/app/i18n/python/transifex.py:33

      auth=self.auth_
    )
    r.raise_for_status()
    d = r.json()
    self.languages_ = set(lang['code'] for lang in d['available_languages'])

  def canonical_lang(self, lang):
    lang = lang.lower()

    for l in self.languages_:
      if l.lower() == lang:
        return l

    match = []
    for l in self.languages_:
      if l.split('_', 1)[0].lower() == lang:
        match.append(l)
    if len(match) > 1:
      raise RuntimeError('Two or more candidates for %s: %s' % (lang, ' '.join(match)))
    if len(match) == 0:
      raise RuntimeError('No language code %s' % lang)
    return match[0]

  def translation(self, lang):
    r = requests.get(
      'https://www.transifex.com/api/2/project/arduino-ide-15/resource/ide-15/translation/%s/?file' % lang,
      auth=self.auth_
    )
    r.raise_for_status()
    r.encoding = 'utf-8'  # workaround for a Transifex issue.
    return r.text

  def pull(self, lang, fname):
    new = self.translation(lang).encode('utf-8')
    new = map(lambda a: a + '\n', new.split('\n'))
    new = update.read_po(new)

View on GitHub (pinned to a0df6e0e83)

Solutions

  1. Request the full language code including the region (e.g. 'pt_BR') so the split('_')[0] prefix still matches but you disambiguate after via exact match or explicit choice.
  2. Inspect the RuntimeError message to see the candidates and pick one explicitly in your script.
  3. Adjust the project's language list in Transifex to avoid duplicate base codes, or filter self.languages_ before calling.
  4. Prefer a candidate deterministically (e.g. sorted(match)[0]) only if arbitrary choice is acceptable.

Example fix

// before
canonical_lang('pt')  # ambiguous: pt_BR vs pt_PT
# after
canonical_lang('pt_BR')
Defensive patterns

Strategy: validation

Validate before calling

candidates = [l for l in project.languages_ if l.split('_', 1)[0].lower() == lang]
if len(candidates) != 1:
    raise ValueError('ambiguous or missing language: %s -> %r' % (lang, candidates))

Try / catch

try:
    code = tx.canonical_lang(lang)
except RuntimeError as e:
    code = sorted_candidates[0]  # or skip language

Prevention

When it happens

Trigger: Calling canonical_lang(lang) when self.languages_ contains two or more codes with the same base, e.g. ['pt_BR', 'pt_PT'] and lang='pt'; also 'zh_CN'/'zh_TW' with 'zh'.

Common situations: Projects containing multiple regional variants of the same language (pt_BR/pt_PT, zh_CN/zh_TW, es_ES/es_MX); automation scripts that resolve base codes for all project languages.

Related errors


AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06). Data as JSON: /api/errors/ef21dab61cbbebae. Report an issue: GitHub.