affaan-m/ECC · error

Legacy language arguments cannot be combined with…

Error message

Legacy language arguments cannot be combined with --profile, --modules, --with, --without, or manifest config selections

What it means

normalizeInstallRequest validates that legacy language arguments (e.g. old --lang style flags) are not mixed with the newer manifest-based selection flags. The install CLI supports two mutually exclusive selection modes: legacy language packs and manifest selections (--profile, --modules, --with, --without, or manifest config entries). Combining them is ambiguous, so the library rejects the request up front.

Solutions

  1. Remove the legacy language arguments and rely solely on --profile/--modules/--with/--without.
  2. Remove the modern manifest flags and use only legacy language arguments if you intentionally want legacy-compat mode.
  3. Update any wrapper scripts or aliases that still inject language flags.
  4. Pass no selection flags at all only if you also intend the 'no selections' error path — you must supply exactly one selection mode.

Example fix

// before
node install.js --lang typescript --profile standard
// after
node install.js --profile standard --modules typescript-modules
Defensive patterns

Strategy: validation

Validate before calling

const hasLegacy = (opts.languages || []).length > 0
const hasManifest = !!(opts.profile || (opts.modules && opts.modules.length) || (opts.with && opts.with.length) || (opts.without && opts.without.length))
if (hasLegacy && hasManifest) throw new Error('Use either legacy language args or manifest selections, not both')

Type guard

function isExclusiveSelection(opts) {
  const legacy = Array.isArray(opts.languages) && opts.languages.length > 0
  const manifest = Boolean(opts.profile) || (Array.isArray(opts.modules) && opts.modules.length > 0) || (Array.isArray(opts.with) && opts.with.length > 0) || (Array.isArray(opts.without) && opts.without.length > 0)
  return !(legacy && manifest)
}

Try / catch

try {
  const req = normalizeInstallRequest(options)
} catch (err) {
  if (err.message.includes('Legacy language arguments')) {
    console.error('Pick one selection mode: legacy languages OR --profile/--modules/--with/--without')
  } else throw err
}

Prevention

When it happens

Trigger: Calling normalizeInstallRequest (directly or via request()) where legacyLanguages.length > 0 AND hasNonLocaleManifestSelection is true, i.e. language arguments were supplied together with a profile, module IDs, included component IDs, or exclusion IDs.

Common situations: Users upgrading from the legacy install syntax run an old command line like `install --lang typescript --profile standard`; shell aliases or wrapper scripts that append language flags to a modern command; documentation examples mixing both flag generations.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/f16941ffaba1ba64. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/install/request.js:141

    ...(options.excludeComponentIds || []),
  ]);
  const legacyLanguages = dedupeStrings(dedupeStrings([
    ...(Array.isArray(options.legacyLanguages) ? options.legacyLanguages : []),
    ...(Array.isArray(options.languages) ? options.languages : []),
  ]).map(language => language.toLowerCase()));
  const hookConsent = resolveHookConsentFlags(options);
  if (hookConsent === 'declined' && moduleIds.includes('hooks-runtime')) {
    throw new Error('--no-hooks cannot be combined with an explicit hooks-runtime module selection');
  }
  const hasManifestBaseSelection = Boolean(profileId) || moduleIds.length > 0 || includeComponentIds.length > 0;
  const hasNonLocaleManifestSelection = Boolean(profileId)
    || moduleIds.length > 0
    || requestedIncludeComponentIds.length > 0
    || excludeComponentIds.length > 0;
  const usingManifestMode = hasManifestBaseSelection || excludeComponentIds.length > 0;

  if (hasNonLocaleManifestSelection && legacyLanguages.length > 0) {
    throw new Error(
      'Legacy language arguments cannot be combined with --profile, --modules, --with, --without, or manifest config selections'
    );
  }

  if (!options.help && !hasManifestBaseSelection && legacyLanguages.length === 0) {
    throw new Error('No install profile, module IDs, included components, or legacy languages were provided');
  }

  return {
    mode: legacyLanguages.length > 0
      ? 'legacy-compat'
      : (usingManifestMode ? 'manifest' : 'legacy-compat'),
    target,
    profileId,
    moduleIds,
    includeComponentIds,
    excludeComponentIds,
    legacyLanguages,

View on GitHub (pinned to 8321021c54)