{"record":{"id":"c15967981e948756","repo":"ansible/ansible","slug":"url-for-repository-not-specified-use-h-for-help","errorCode":null,"errorMessage":"URL for repository not specified, use -h for help","messagePattern":"URL for repository not specified, use -h for help","errorType":"exception","errorClass":"AnsibleOptionsError","httpStatus":null,"severity":"error","filePath":"lib/ansible/cli/pull.py","lineNumber":179,"sourceCode":"        options = super(PullCLI, self).post_process_args(options)\n\n        if not options.dest:\n            hostname = socket.getfqdn()\n            # use a hostname dependent directory, in case of $HOME on nfs\n            options.dest = os.path.join(C.ANSIBLE_HOME, 'pull', hostname)\n\n        if os.path.exists(options.dest) and not os.path.isdir(options.dest):\n            raise AnsibleOptionsError(\"%s is not a valid or accessible directory.\" % options.dest)\n\n        if options.sleep:\n            try:\n                secs = secrets.randbelow(int(options.sleep))\n                options.sleep = secs\n            except ValueError:\n                raise AnsibleOptionsError(\"%s is not a number.\" % options.sleep)\n\n        if not options.url:\n            raise AnsibleOptionsError(\"URL for repository not specified, use -h for help\")\n\n        if options.module_name not in self.REPO_CHOICES:\n            raise AnsibleOptionsError(\"Unsupported repo module %s, choices are %s\" % (options.module_name, ','.join(self.REPO_CHOICES)))\n\n        display.verbosity = options.verbosity\n        self.validate_conflicts(options)\n\n        return options\n\n    def run(self):\n        \"\"\" use Runner lib to do SSH things \"\"\"\n\n        super(PullCLI, self).run()\n\n        # log command line\n        now = datetime.datetime.now()\n        display.display(now.strftime(\"Starting Ansible Pull at %F %T\"))\n        display.display(' '.join(sys.argv))","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/ansible/ansible/blob/9cf16a4aca7898481c257f1e17ad28d0b67b1f85/lib/ansible/cli/pull.py#L161-L197","documentation":"`ansible-pull` clones a repository before running its playbook, so a source URL is mandatory. `post_process_args` raises `AnsibleOptionsError` when `options.url` (from `-U/--url`) is empty — there is no default and no way to proceed.","triggerScenarios":"Running `ansible-pull` with no `-U` at all; passing `-U` with an empty value (`-U \"\"`) from an unset variable in a systemd unit or cron line.","commonSituations":"Templated systemd units/cron jobs where the URL environment variable is not exported; shell quoting mistakes that swallow the value; typos using `--url` long form with `=` and nothing after.","solutions":["Supply the repo URL: `ansible-pull -U https://github.com/org/repo.git ...`.","Check the systemd unit / cron script for empty variables (`set -u`, `EnvironmentFile`) and add a guard before invoking ansible-pull.","Run `ansible-pull -h` to confirm the exact option spelling being used."],"exampleFix":"# before\nansible-pull -i localhost,\n\n# after\nansible-pull -U https://github.com/org/repo.git -i localhost,","handlingStrategy":"validation","validationCode":"url = os.environ.get('PULL_URL')\nassert url, 'PULL_URL must be set (ansible-pull -U)'\nrun(['ansible-pull', '-U', url])","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fail fast in systemd/cron wrappers when the repo URL variable is empty.","Use `set -u` in wrapper scripts to catch unset variables."],"tags":["ansible-pull","cli","argument-validation","git"],"backgroundTag":null,"analyzedSha":"9cf16a4aca7898481c257f1e17ad28d0b67b1f85","analyzedAt":"2026-08-15T00:15:47.100Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}