affaan-m/ECC · error
Unsupported locale: " ". Supported locales
Error message
Unsupported locale: "${locale}". Supported locales: ${listSupportedLocales().join(', ')} What it means
normalizeInstallRequest resolves the locale from options or config and maps it through LOCALE_ALIAS_TO_COMPONENT_ID. If a locale is provided but has no alias mapping (not in the supported set returned by listSupportedLocales()), it throws this error listing the supported locales.
Solutions
- Use one of the locales listed in the error message (from listSupportedLocales()).
- Try the base language code (e.g. `zh` instead of `zh-TW`) if only base aliases are mapped.
- Fix casing/typos so the value matches an entry in LOCALE_ALIAS_TO_COMPONENT_ID.
- Remove the locale from your config file if you didn't intend to install a translated component set.
Example fix
// before install --target claude --locale zh-TW // if unsupported // after install --target claude --locale zh-CN // pick from the supported list in the message
Defensive patterns
Strategy: validation
Validate before calling
const supported = listSupportedLocales();
if (locale && !supported.includes(locale)) {
throw new Error(`unsupported locale "${locale}"; pick one of: ${supported.join(', ')}`);
} Type guard
function isSupportedLocale(l) { return Boolean(LOCALE_ALIAS_TO_COMPONENT_ID[l]); } Try / catch
try {
const req = normalizeInstallRequest(options);
} catch (e) {
if (e.message.startsWith('Unsupported locale')) {
console.error(`${e.message} — see listSupportedLocales() for valid codes.`);
return;
}
throw e;
} Prevention
- Consult listSupportedLocales() before scripting a locale install.
- Use base language codes unless a region alias is explicitly documented.
- Strip stale `locale` keys from config files inherited from other tools.
- Add a unit test that validates any user-supplied locale against the alias map.
When it happens
Trigger: Calling normalizeInstallRequest (or runTests) with options.locale or config.locale set to an unmapped value: misspelled codes ('en-US' if only 'en' is mapped), wrong casing beyond alias handling, an entirely unsupported language, or an empty-but-truthy string.
Common situations: Typos in the locale code; using a region variant the installer doesn't ship ('fr-CA' when only 'fr' exists); a config file carrying a locale from another tool's naming scheme; copy-pasting a BCP-47 tag where only base aliases are supported.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- --locale can only be used with --target claude or --target…
- all overlays must be readable local files
- all takes must be readable local files
- Arguments must not contain NUL bytes.
- asset name must be a simple filename stem (letters, digits…
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/3baf4d3bd312917d.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/request.js:106
}
}
return parsed;
}
function normalizeInstallRequest(options = {}) {
const config = options.config && typeof options.config === 'object'
? options.config
: null;
const profileId = options.profileId || config?.profileId || null;
const target = options.target || config?.target || 'claude';
const moduleIds = validateInstallModuleIds(
dedupeStrings([...(config?.moduleIds || []), ...(options.moduleIds || [])])
);
const locale = options.locale || config?.locale || null;
const localeComponentId = locale ? LOCALE_ALIAS_TO_COMPONENT_ID[locale] : null;
if (locale && !localeComponentId) {
throw new Error(
`Unsupported locale: "${locale}". Supported locales: ${listSupportedLocales().join(', ')}`
);
}
if (locale && target !== 'claude' && target !== 'claude-project') {
throw new Error('--locale can only be used with --target claude or --target claude-project');
}
const requestedIncludeComponentIds = dedupeStrings([
...(config?.includeComponentIds || []),
...(options.includeComponentIds || []),
]);
const includeComponentIds = dedupeStrings([
...requestedIncludeComponentIds,
...(localeComponentId ? [localeComponentId] : []),
]);
const excludeComponentIds = dedupeStrings([
...(config?.excludeComponentIds || []),
...(options.excludeComponentIds || []),
]);View on GitHub (pinned to 8321021c54)