{"record":{"id":"a4b4c5055b0a92c8","repo":"angular/angular-cli","slug":"option-registry-must-be-a-valid-url","errorCode":null,"errorMessage":"Option --registry must be a valid URL.","messagePattern":"Option --registry must be a valid URL\\.","errorType":"validation","errorClass":"CommandModuleError","httpStatus":null,"severity":"error","filePath":"packages/angular/cli/src/commands/add/cli.ts","lineNumber":139,"sourceCode":"        default: false,\n      })\n      .option('skip-confirmation', {\n        description:\n          'Skip asking a confirmation prompt before installing and executing the package. ' +\n          'Ensure package name is correct prior to using this option.',\n        type: 'boolean',\n        default: false,\n      })\n      .check(({ registry }) => {\n        if (registry === undefined) {\n          return true;\n        }\n\n        if (typeof registry === 'string' && URL.canParse(registry)) {\n          return true;\n        }\n\n        throw new CommandModuleError('Option --registry must be a valid URL.');\n      })\n      // Prior to downloading we don't know the full schema and therefore we cannot be strict on the options.\n      // Possibly in the future update the logic to use the following syntax:\n      // `ng add @angular/localize -- --package-options`.\n      .strict(false);\n\n    const collectionName = this.getCollectionName();\n    if (!collectionName) {\n      return localYargs;\n    }\n\n    const workflow = this.getOrCreateWorkflowForBuilder(collectionName);\n\n    try {\n      const collection = workflow.engine.createCollection(collectionName);\n      const options = await this.getSchematicOptions(collection, this.schematicName, workflow);\n\n      return this.addSchemaOptionsToCommand(localYargs, options);","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/commands/add/cli.ts#L121-L157","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nng add @angular/localize --registry localhost:4873\n\n// after\nng add @angular/localize --registry http://localhost:4873","handlingStrategy":"validation","validationCode":"function isValidRegistryUrl(value) {\n  return typeof value === 'string' && URL.canParse(value);\n}\nconst registry = process.argv[/* ... */];\nif (!isValidRegistryUrl(registry)) {\n  throw new Error(`--registry must be an absolute URL, got: ${registry}`);\n}","typeGuard":"function isHttpUrl(value: unknown): value is string {\n  if (typeof value !== 'string' || !URL.canParse(value)) return false;\n  const { protocol } = new URL(value);\n  return protocol === 'http:' || protocol === 'https:';\n}","tryCatchPattern":"try {\n  await runNgAdd(pkg, { registry });\n} catch (e) {\n  if (e instanceof CommandModuleError && e.message.includes('--registry must be a valid URL')) {\n    console.error(`Invalid registry '${registry}'. Use e.g. https://registry.npmjs.org`);\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["angular-cli","ng-add","cli-validation","url"],"backgroundTag":"invalid-url-option","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}