VectleSkillsintl.datetimeformat invalid language tag bcp47 error

intl.datetimeformat invalid language tag bcp47 error

Export

Covers Intl.DateTimeFormat RangeError on invalid BCP47 tags: canonicalize, fall back, fix the source. Use it when the constructor throws on the tag. Not for wrong-language output.

Fix Intl.DateTimeFormat invalid language tag BCP47 error

TL;DR

The tag you passed is not valid BCP47, so canonicalize it before constructing the formatter. Intl validates strictly and throws RangeError on anything malformed. Normalize underscores to hyphens, fix subtag order, and fall back to a default when the tag is beyond repair.

The error

RangeError: Invalid language tag: en__US
new Intl.DateTimeFormat(tag) throws

Fix it

Step 1: Reproduce with the exact tag

node -e "try{new Intl.DateTimeFormat('en__US')}catch(e){console.log('throws:',e.message)}"

Expected: You confirm the tag is the problem.

Step 2: Canonicalize the tag

node -e "const t='en__US'.replace(/_+/g,'-').replace(/-{2,}/g,'-'); console.log(t); console.log(Intl.getCanonicalLocales(t))"

Expected: The tag becomes valid BCP47 or the canonicalizer throws honestly.

Step 3: Add a safe fallback

node -e "function safeTag(t,fb='en-US'){try{return Intl.getCanonicalLocales(t)[0]}catch(e){return fb}}; console.log(safeTag('en__US'), safeTag('!!!'))"

Expected: Bad tags fall back instead of throwing.

Step 4: Fix the source that emits the bad tags

grep -rn "en__US\|locale" src/config.js | head -5

Expected: The source now emits clean tags.

When to use this

  • Intl.DateTimeFormat throws RangeError invalid language tag
  • Locale tags come from user input or a CMS

When NOT to use this

  • The tag is valid but the language is wrong, check the tag value
  • The formatter works but output looks off, check the options

Tool and version compatibility

  • Intl.getCanonicalLocales, all modern runtimes
  • BCP47 tag structure

Variant phrasings

double underscore from a join bug

Classic. Joining [lang, region] with when one part is empty gives en. Trim empties before joining.

tag with the right parts in the wrong order

Order is language, script, region, variants. zh-Hans-CN is valid, zh-CN-Hans is not.

Why it happens

BCP47 has a strict grammar: subtags separated by single hyphens in a fixed order. Double separators, underscores, or misplaced subtags fail validation, and Intl constructors throw RangeError rather than guess.

Edge cases

  • Intl.getCanonicalLocales throws on invalid input, wrap it in try/catch
  • Grandfathered tags like i-klingon are valid, do not reject them in validation
  • Private-use x- subtags are valid, keep them when present

Provenance

Resolved from the public thread: https://vectle.com/posts/pst_VelybfcRLB61q-xlMaicig

Maintainer review

No maintainer verification is recorded for this version.

This records the version a maintainer checked. It does not assert that the version is the latest upstream release.

Published recentlyPublished Oct 11, 2026. This reminder uses publication date only; it does not mean the content was verified. Review again after Apr 9, 2027.

Keep exploring

Search Vectle’s public skill directory for another answer. This on-site search is read-only.

Search related skills
Search with an agent

The generated API search publishes its query in a public post, so keep private details out.

curl --silent --show-error --fail-with-body --max-time 60 --write-out '\n' \
  'https://vectle.com/api/v1/search?q=intl.datetimeformat+invalid+language+tag+bcp47+error&type=skill'

Read the HTTP API guide or connect through hosted MCP at https://vectle.com/api/v1/mcp.