angular/angular-cli · error · Error
Unsupported package specifier type: ${type}
Error message
Unsupported package specifier type: ${type} What it means
The default branch of the type switch in PackageManager.getManifest. npm-package-arg resolved the specifier to a type the Angular CLI does not handle (anything other than range, version, tag, directory, file, remote, or git). This guards against unknown or future npa specifier types.
Source
Thrown at packages/angular/cli/src/package-managers/package-manager.ts:642
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}`);
}
// The package will be installed in `<temp>/node_modules/<name>`.
const packagePath = join(workingDirectory, 'node_modules', packageName);
const manifestPath = join(packagePath, 'package.json');
const manifest = await this.host.readFile(manifestPath);
return JSON.parse(manifest);
} finally {
await cleanup();
}
}
default:
throw new Error(`Unsupported package specifier type: ${type}`);
}
}
private async getTemporaryDirectory(): Promise<string | undefined> {
const { tempDirectory } = this.options;
if (tempDirectory && !relative(this.cwd, tempDirectory).startsWith('..')) {
try {
await this.host.stat(tempDirectory);
} catch {
// If the cache directory doesn't exist, create it.
await this.host.mkdir(tempDirectory, { recursive: true });
}
return tempDirectory;
}
const tempOptions = ['node_modules'];View on GitHub (pinned to bb72145f9a)
Solutions
- Log/print npa(specifier) to see the resolved type and rewrite the specifier into a supported form (registry range, tag, directory, file, remote tarball, or git URL).
- If passing an npa.Result programmatically, normalize its `type` to one of the supported values before calling getManifest.
- Align the npa version used by your tooling with the one bundled by @angular/cli to avoid classification differences.
- Fetch the manifest directly from the registry yourself as a fallback if the specifier cannot be expressed in a supported form.
Example fix
// before
await pm.getManifest({ name: 'x', type: 'unknown', fetchSpec: 'x' } as npa.Result);
// after
await pm.getManifest('x@^1.0.0'); Defensive patterns
Strategy: type-guard
Validate before calling
import npa from 'npm-package-arg';
const SUPPORTED = new Set(['range', 'version', 'tag', 'directory', 'file', 'remote', 'git']);
const r = npa(specifier);
if (!SUPPORTED.has(r.type)) {
throw new Error(`Unsupported specifier type '${r.type}' for '${specifier}'`);
} Type guard
const SUPPORTED_TYPES = ['range', 'version', 'tag', 'directory', 'file', 'remote', 'git'] as const;
type SupportedType = typeof SUPPORTED_TYPES[number];
function isSupportedType(t: string): t is SupportedType {
return (SUPPORTED_TYPES as readonly string[]).includes(t);
} Try / catch
try {
const manifest = await pm.getManifest(specifier);
} catch (err) {
if ((err as Error).message.startsWith('Unsupported package specifier type')) {
logger.error(`Rewrite '${specifier}' into a supported form (name@version, path, or URL)`);
} else throw err;
} Prevention
- Check npa(specifier).type before calling getManifest when feeding programmatic specifiers
- Keep npa versions consistent with @angular/cli to avoid classification drift
- Normalize alias/custom specifiers to registry form upstream
- Log the resolved npa.Result when errors occur to ease diagnosis
When it happens
Trigger: getManifest called with a specifier string that npa classifies as an exotic type — practically rare, but possible via manually constructed npa.Result objects with a custom/unsupported `type` field, or unexpected npa version behavior on odd inputs.
Common situations: Programmatic tooling passing pre-parsed npa.Result objects with nonstandard types, npa version mismatches changing classification of edge-case specifiers, or alias/other specifier forms not covered by the switch.
Related errors
- Could not parse location from specifier: ${specifier}
- Could not determine package name for specifier: ${specifier}
- Unable to install packages
- Unable to load package information from registry.
- Unable to fetch package information for '${context.packageId
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/9a40d1a68a2ab442.
Report an issue: GitHub.