{"record":{"id":"88d4d4c59d34aa5e","repo":"affaan-m/ECC","slug":"failed-to-save-package-manager-config-to-configp","errorCode":null,"errorMessage":"Failed to save package manager config to ${configPath}: ${err.message}","messagePattern":"Failed to save package manager config to (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/package-manager.js","lineNumber":281,"sourceCode":" * Set project's preferred package manager\n */\nfunction setProjectPackageManager(pmName, projectDir = process.cwd()) {\n  if (!PACKAGE_MANAGERS[pmName]) {\n    throw new Error(`Unknown package manager: ${pmName}`);\n  }\n\n  const configDir = path.join(projectDir, '.claude');\n  const configPath = path.join(configDir, 'package-manager.json');\n\n  const config = {\n    packageManager: pmName,\n    setAt: new Date().toISOString()\n  };\n\n  try {\n    writeFile(configPath, JSON.stringify(config, null, 2));\n  } catch (err) {\n    throw new Error(`Failed to save package manager config to ${configPath}: ${err.message}`);\n  }\n  return config;\n}\n\n// Allowed characters in script/binary names: alphanumeric, dash, underscore, dot, slash, @\n// This prevents shell metacharacter injection while allowing scoped packages (e.g., @scope/pkg)\nconst SAFE_NAME_REGEX = /^[@a-zA-Z0-9_./-]+$/;\n\n/**\n * Get the command to run a script\n * @param {string} script - Script name (e.g., \"dev\", \"build\", \"test\")\n * @param {object} options - { projectDir }\n * @throws {Error} If script name contains unsafe characters\n */\nfunction getRunCommand(script, options = {}) {\n  if (!script || typeof script !== 'string') {\n    throw new Error('Script name must be a non-empty string');\n  }","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/package-manager.js#L263-L299","documentation":"Thrown by setProjectPackageManager when writeFile(configPath, ...) fails while writing the project-level preference file at <projectDir>/.claude/package-manager.json. Unlike saveConfig (global), this writes directly via utils.writeFile without first ensuring the .claude directory exists, so a missing <projectDir>/.claude is the most common cause (ENOENT). The underlying error and the resolved configPath are included for diagnosis.","triggerScenarios":"Fires in the catch of writeFile inside setProjectPackageManager. Occurs when <projectDir>/.claude does not exist (utils.writeFile may not mkdir parents), when the project dir is read-only, when configPath resolves to an existing directory, on ENOSPC, or when projectDir itself does not exist.","commonSituations":"First-time project setup where .claude was never created; projectDir passed as a non-existent path; running in a fresh checkout without the .claude dir; read-only project mount; projectDir defaulting to process.cwd() inside a sandbox where cwd is not writable; an existing directory named package-manager.json.","solutions":["Create <projectDir>/.claude before calling: fs.mkdirSync(path.join(projectDir,'.claude'), { recursive:true }).","Pass a projectDir that exists and is writable.","Remove a conflicting directory/file at <projectDir>/.claude/package-manager.json.","Free disk space or remount read-write if the project is on a read-only filesystem."],"exampleFix":"// before: .claude does not exist yet -> writeFile throws ENOENT\nsetProjectPackageManager('pnpm', projectDir); // throws [299]\n\n// after: ensure the config dir exists first\nconst fs = require('fs'); const path = require('path');\nfs.mkdirSync(path.join(projectDir, '.claude'), { recursive: true });\nsetProjectPackageManager('pnpm', projectDir);","handlingStrategy":"try-catch","validationCode":"const fs = require('fs'); const path = require('path');\nfunction assertProjectConfigWritable(projectDir) {\n  const dir = path.join(projectDir, '.claude');\n  fs.mkdirSync(dir, { recursive: true });\n  const probe = path.join(dir, '.ecc-write-probe');\n  fs.writeFileSync(probe, ''); fs.unlinkSync(probe);\n}\nassertProjectConfigWritable(projectDir);\nsetProjectPackageManager('pnpm', projectDir);","typeGuard":"null","tryCatchPattern":"try {\n  setProjectPackageManager(pmName, projectDir);\n} catch (err) {\n  if (/Failed to save package manager config to/.test(err.message)) {\n    // most common cause: <projectDir>/.claude missing. Create it and retry.\n    fs.mkdirSync(path.join(projectDir, '.claude'), { recursive: true });\n    setProjectPackageManager(pmName, projectDir);\n  } else throw err;\n}","preventionTips":["Create <projectDir>/.claude before calling; utils.writeFile does not mkdir parents.","Pass a projectDir that exists and is writable; do not rely on cwd inside sandboxes.","Remove any directory/file conflicting with package-manager.json.","Ensure the project filesystem is mounted read-write."],"tags":["package-manager","filesystem","permissions","project-config","write-error","enoent"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}