angular/angular-cli · error · CommandModuleError
Option --registry must be a valid URL.
Error message
Option --registry must be a valid URL.
What it means
The 'ng add' command validates its --registry option with a yargs coerce/check that requires the value to be a string parseable by URL.canParse. If a string registry is passed that is not a valid absolute URL (e.g. missing scheme), a CommandModuleError 'Option --registry must be a valid URL.' is thrown before any install work starts.
Source
Thrown at packages/angular/cli/src/commands/add/cli.ts:139
default: false,
})
.option('skip-confirmation', {
description:
'Skip asking a confirmation prompt before installing and executing the package. ' +
'Ensure package name is correct prior to using this option.',
type: 'boolean',
default: false,
})
.check(({ registry }) => {
if (registry === undefined) {
return true;
}
if (typeof registry === 'string' && URL.canParse(registry)) {
return true;
}
throw new CommandModuleError('Option --registry must be a valid URL.');
})
// Prior to downloading we don't know the full schema and therefore we cannot be strict on the options.
// Possibly in the future update the logic to use the following syntax:
// `ng add @angular/localize -- --package-options`.
.strict(false);
const collectionName = this.getCollectionName();
if (!collectionName) {
return localYargs;
}
const workflow = this.getOrCreateWorkflowForBuilder(collectionName);
try {
const collection = workflow.engine.createCollection(collectionName);
const options = await this.getSchematicOptions(collection, this.schematicName, workflow);
return this.addSchemaOptionsToCommand(localYargs, options);View on GitHub (pinned to bb72145f9a)
Solutions
- Pass a fully-qualified URL: 'ng add @scope/pkg --registry https://registry.npmjs.org'.
- Add the scheme for local registries: 'http://localhost:4873' instead of 'localhost:4873'.
- If the registry comes from a variable/script, validate it with new URL(value) before invoking ng add.
- Alternatively configure the registry in .npmrc (registry=...) so --registry is not needed.
Example fix
// before ng add @angular/localize --registry localhost:4873 // after ng add @angular/localize --registry http://localhost:4873
Defensive patterns
Strategy: validation
Validate before calling
function isValidRegistryUrl(value) {
return typeof value === 'string' && URL.canParse(value);
}
const registry = process.argv[/* ... */];
if (!isValidRegistryUrl(registry)) {
throw new Error(`--registry must be an absolute URL, got: ${registry}`);
} Type guard
function isHttpUrl(value: unknown): value is string {
if (typeof value !== 'string' || !URL.canParse(value)) return false;
const { protocol } = new URL(value);
return protocol === 'http:' || protocol === 'https:';
} Try / catch
try {
await runNgAdd(pkg, { registry });
} catch (e) {
if (e instanceof CommandModuleError && e.message.includes('--registry must be a valid URL')) {
console.error(`Invalid registry '${registry}'. Use e.g. https://registry.npmjs.org`);
} else { throw e; }
} Prevention
- Always include the scheme (http:// or https://) in registry values.
- Validate registry URLs with new URL(value) in wrapper scripts before spawning ng add.
- Prefer configuring registries in .npmrc rather than on the command line.
- Quote URLs in shells that treat '//' specially.
When it happens
Trigger: Running 'ng add <package> --registry <value>' where <value> is a string that URL.canParse rejects — e.g. 'localhost:4873', 'my-registry.local', 'http:/wrong', or an empty string.
Common situations: Pointing ng add at a local npm proxy like Verdaccio and passing the host without the 'http://' scheme; copy-pasting a registry value from .npmrc without the protocol; shell mangling of '//' in URLs.
Related errors
- Unable to load package information from registry: ${e.messag
- Could not find ${level} workspace.
- Invalid config found at ${workspace.filePath}. CLI should be
- Could not find a ${level} workspace. Are you in a project?
- Could not find the '${builderConf}' builder's node package.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/a4b4c5055b0a92c8.
Report an issue: GitHub.