{"record":{"id":"8b205df266a9fadf","repo":"angular/angular-cli","slug":"failed-to-parse-package-manager-output-e-instan","errorCode":null,"errorMessage":"Failed to parse package manager output: ${e instanceof Error ? e.message : ''}","messagePattern":"Failed to parse package manager output: (.+?)","errorType":"exception","errorClass":"PackageManagerError","httpStatus":null,"severity":"error","filePath":"packages/angular/cli/src/package-managers/package-manager.ts","lineNumber":322,"sourceCode":"    // structured error, re-throw the original error now.\n    if (thrownError) {\n      throw thrownError;\n    }\n\n    // If we reach this point, the command succeeded and no structured error was found.\n    // We can now safely parse the successful output.\n    try {\n      const result = parser(stdout, this.options.logger);\n      if (cache && cacheKey) {\n        cache.set(cacheKey, result);\n      }\n\n      return result;\n    } catch (e) {\n      const message = `Failed to parse package manager output: ${\n        e instanceof Error ? e.message : ''\n      }`;\n      throw new PackageManagerError(message, stdout, stderr, exitCode);\n    }\n  }\n\n  /**\n   * Adds a package to the project's dependencies.\n   * @param packageName The name of the package to add.\n   * @param save The save strategy to use.\n   * - `exact`: The package will be saved with an exact version.\n   * - `tilde`: The package will be saved with a tilde version range (`~`).\n   * - `none`: The package will be saved with the default version range (`^`).\n   * @param asDevDependency Whether to install the package as a dev dependency.\n   * @param noLockfile Whether to skip updating the lockfile.\n   * @param options Extra options for the command.\n   * @returns A promise that resolves when the command is complete.\n   */\n  async add(\n    packageName: string,\n    save: 'exact' | 'tilde' | 'none',","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/package-managers/package-manager.ts#L304-L340","documentation":"Thrown when the package manager command succeeded (exit 0, no structured error parsed) but the CLI's parser for that package manager's output threw — usually because stdout was not the expected JSON/structured format. #fetchAndParse wraps any parser exception in a PackageManagerError with the message 'Failed to parse package manager output: <original message>' plus the raw stdout/stderr/exitCode, so the caller can inspect what the tool actually printed.","triggerScenarios":"Calling dependencies(), getRegistryMetadata(), or manifest() where the output parser (e.g. getRegistryMetadata/getRegistryManifest parsers) calls JSON.parse or accesses expected fields on stdout that is empty, truncated, a warning banner, or human-readable text instead of machine-readable output.","commonSituations":"npm/yarn wrapper scripts or shell aliases injecting extra output; a global npm config (e.g. `loglevel`, `--json` overridden, init banner) polluting stdout; registry returning an HTML error page captured as output; package manager version whose output shape differs from what the CLI descriptor expects (version drift); output truncated by the OS or low disk.","solutions":["Inspect e.stdout/e.stderr on the PackageManagerError to see what the package manager actually printed, then fix whatever polluted the output.","Verify the package manager binary works directly: run the equivalent `npm view <pkg> --json` / `yarn info` command manually and check it prints valid JSON.","Check for shell wrappers, aliases, or npm config (`.npmrc` settings like `loglevel`, `progress`, `fund`, `audit`) that add non-JSON text to stdout.","Confirm the installed package manager version is supported by the Angular CLI and not a heavily modified fork.","Free disk space / increase available memory if stdout appears truncated."],"exampleFix":"// before: debug via opaque failure\nconst manifest = await pm.getManifest('lodash@^4');\n\n// after: surface the raw output on parse failure\ntry {\n  const manifest = await pm.getManifest('lodash@^4');\n} catch (e) {\n  if (e instanceof PackageManagerError && e.message.startsWith('Failed to parse package manager output')) {\n    console.error('Raw stdout was:', e.stdout);\n    // e.g. reveals an npm notice/banner breaking JSON.parse\n  } else {\n    throw e;\n  }\n}","handlingStrategy":"try-catch","validationCode":"import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nconst run = promisify(exec);\n// Verify the package manager emits clean JSON before using library methods\nconst { stdout } = await run('npm view lodash name --json');\nJSON.parse(stdout); // throws early if output is polluted/non-JSON","typeGuard":"function isOutputParseError(e: unknown): e is PackageManagerError {\n  return e instanceof PackageManagerError\n    && e.message.startsWith('Failed to parse package manager output');\n}","tryCatchPattern":"try {\n  const deps = await pm.dependencies();\n} catch (e) {\n  if (isOutputParseError(e)) {\n    console.error('Unexpected tool output:', JSON.stringify({ stdout: e.stdout, stderr: e.stderr }, null, 2));\n  } else {\n    throw e;\n  }\n}","preventionTips":["Avoid shell aliases/wrappers around npm/yarn that print banners or notices to stdout.","Keep the package manager version aligned with versions the Angular CLI supports; version drift changes output shapes.","Check .npmrc for settings that append human-readable output (progress, fund, audit notices) and disable them for automation.","Ensure sufficient disk/memory so command output is not truncated.","When the error occurs, dump e.stdout and e.stderr — the raw output reveals exactly which extra text broke JSON parsing."],"tags":["parsing","json","package-manager","angular-cli"],"backgroundTag":"output-parse-failed","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}