angular/angular-cli · error · Error

Could not parse location from specifier: ${specifier}

Error message

Could not parse location from specifier: ${specifier}

What it means

Thrown by PackageManager.getManifest when the specifier resolves via npm-package-arg (npa) to type 'file', 'remote', or 'git' but has no fetchSpec, meaning no concrete location (file path, tarball URL, or git URL) could be extracted from the input string. The CLI needs that location to install the package into a temporary directory and read its manifest.

Source

Thrown at packages/angular/cli/src/package-managers/package-manager.ts:611

        }

        return this.getRegistryManifest(name, versionSpec, options);
      }
      case 'directory': {
        if (!fetchSpec) {
          throw new Error(`Could not parse directory path from specifier: ${specifier}`);
        }

        const manifestPath = join(fetchSpec, 'package.json');
        const manifest = await this.host.readFile(manifestPath);

        return JSON.parse(manifest);
      }
      case 'file':
      case 'remote':
      case 'git': {
        if (!fetchSpec) {
          throw new Error(`Could not parse location from specifier: ${specifier}`);
        }

        // Caching is not supported for non-registry specifiers.
        const { workingDirectory, cleanup } = await this.acquireTempPackage(fetchSpec, {
          ...options,
          ignoreScripts: true,
        });

        try {
          // Discover the package name by reading the temporary `package.json` file.
          // The package manager will have added the package to the `dependencies`.
          const tempManifest = await this.host.readFile(join(workingDirectory, 'package.json'));
          const { dependencies } = JSON.parse(tempManifest) as PackageManifest;
          const packageName = dependencies && Object.keys(dependencies)[0];

          if (!packageName) {
            throw new Error(`Could not determine package name for specifier: ${specifier}`);
          }

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Check the specifier string for typos or missing URL/path portions and re-run with a complete specifier (e.g. 'https://.../pkg.tgz', 'git+https://github.com/user/repo.git', or an existing file path).
  2. If constructing an npa.Result manually, ensure fetchSpec is populated before calling getManifest.
  3. Use a registry range/version/tag specifier (e.g. 'pkg@^1.2.3') instead if a file/remote/git source is not strictly required.
  4. Validate the specifier with npa() beforehand and assert the resolved type and fetchSpec are present.

Example fix

// before
await pm.getManifest('git+ssh://'); // no repo URL -> throws
// after
await pm.getManifest('git+https://github.com/angular/angular-cli.git');
Defensive patterns

Strategy: validation

Validate before calling

import npa from 'npm-package-arg';
const r = npa(specifier);
if (['file', 'remote', 'git'].includes(r.type) && !r.fetchSpec) {
  throw new Error(`Specifier '${specifier}' of type '${r.type}' has no fetchSpec`);
}
await pm.getManifest(specifier);

Type guard

function hasFetchSpec(r: npa.Result): r is npa.Result & { fetchSpec: string } {
  return typeof r.fetchSpec === 'string' && r.fetchSpec.length > 0;
}

Try / catch

try {
  const manifest = await pm.getManifest(specifier);
} catch (err) {
  if ((err as Error).message.startsWith('Could not parse location from specifier')) {
    logger.error(`Invalid specifier '${specifier}': provide a full path/URL`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling getManifest with a malformed file/remote/git specifier such as an empty tarball URL, a bare 'git+...' string without a URL, or a manually constructed npa.Result where fetchSpec is undefined/null.

Common situations: Hand-editing package specifiers in ng update/add workflows, passing a git shorthand with a typo (e.g. 'github:user/repo' with a missing repo), copying a specifier that lost its URL part, or programmatic tooling building specifier objects incorrectly.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/e3c374f88c7a96b7. Report an issue: GitHub.