{"record":{"id":"69cef61866603d92","repo":"affaan-m/ECC","slug":"unknown-package-manager-pmname","errorCode":null,"errorMessage":"Unknown package manager: ${pmName}","messagePattern":"Unknown package manager: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/package-manager.js","lineNumber":246,"sourceCode":"  // NOTE: Previously this called getAvailablePackageManagers() which spawns\n  // child processes (where.exe/which) for each PM. This caused plugin freezes\n  // on Windows (see #162) because session-start hooks run during Bun init,\n  // and the spawned processes exceed Bun's spawn limit.\n  // Steps 1-5 already cover all config-based and file-based detection.\n  // If none matched, npm is the safe default.\n  return {\n    name: 'npm',\n    config: PACKAGE_MANAGERS.npm,\n    source: 'default'\n  };\n}\n\n/**\n * Set user's preferred package manager (global)\n */\nfunction setPreferredPackageManager(pmName) {\n  if (!PACKAGE_MANAGERS[pmName]) {\n    throw new Error(`Unknown package manager: ${pmName}`);\n  }\n\n  const config = loadConfig() || {};\n  config.packageManager = pmName;\n  config.setAt = new Date().toISOString();\n\n  try {\n    saveConfig(config);\n  } catch (err) {\n    throw new Error(`Failed to save package manager preference: ${err.message}`);\n  }\n\n  return config;\n}\n\n/**\n * Set project's preferred package manager\n */","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/package-manager.js#L228-L264","documentation":"Thrown by setPreferredPackageManager when pmName is not a key of PACKAGE_MANAGERS. The package-manager module only recognizes npm, pnpm, yarn, and bun; any other value (typos, case variants, retired managers) is rejected before touching global config. This is the input-validation gate for the global setter, distinct from the project-level setter which throws the same message at a different call site.","triggerScenarios":"Fires when PACKAGE_MANAGERS[pmName] is undefined in setPreferredPackageManager. Reached by calling setPreferredPackageManager('pnpm' typo'd as 'pnmp'), with wrong case ('Npm'), with a retired manager name, or with an empty/non-string value that is not a key.","commonSituations":"Typo in the manager name; case sensitivity ('Yarn' vs 'yarn'); passing a versioned string like 'pnpm@8' (the setter wants the bare name, unlike package.json's packageManager field); shell variable expansion producing an empty string; user typing a manager ECC does not support (e.g., 'volta').","solutions":["Pass one of: 'npm', 'pnpm', 'yarn', 'bun' (lowercase, no version).","Strip any '@version' suffix before calling: pmName.split('@')[0].","Lowercase the input: pmName.toLowerCase().","Source the value from Object.keys(PACKAGE_MANAGERS) in a menu rather than free-text."],"exampleFix":"// before\nsetPreferredPackageManager('pnpm@8'); // throws [296]\nsetPreferredPackageManager('Yarn');    // throws [296]\n\n// after\nsetPreferredPackageManager('pnpm');\nsetPreferredPackageManager('yarn');","handlingStrategy":"validation","validationCode":"const { PACKAGE_MANAGERS } = require('./scripts/lib/package-manager');\nfunction assertKnownPm(pmName) {\n  if (!PACKAGE_MANAGERS[pmName]) {\n    throw new Error(`Unknown package manager '${pmName}'. Allowed: ${Object.keys(PACKAGE_MANAGERS).join(', ')}`);\n  }\n}\nassertKnownPm(pmName);\nsetPreferredPackageManager(pmName);","typeGuard":"function isSupportedPackageManager(name) {\n  return name === 'npm' || name === 'pnpm' || name === 'yarn' || name === 'bun';\n}","tryCatchPattern":"try {\n  setPreferredPackageManager(pmName);\n} catch (err) {\n  if (/Unknown package manager/.test(err.message)) {\n    const cleaned = String(pmName).toLowerCase().split('@')[0];\n    if (isSupportedPackageManager(cleaned)) setPreferredPackageManager(cleaned);\n    else throw err;\n  } else throw err;\n}","preventionTips":["Pass the bare lowercase manager name (npm, pnpm, yarn, bun) — never with @version.","Lowercase user input before calling.","Build menus from Object.keys(PACKAGE_MANAGERS) rather than free text.","Guard for null/undefined when the name comes from detection."],"tags":["package-manager","validation","input-validation","global-config"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}