{"record":{"id":"e7616d00f5324c74","repo":"HumanSignal/label-studio","slug":"provide-project-id-or-organization-id","errorCode":null,"errorMessage":"Provide --project <id> or --organization <id>","messagePattern":"Provide --project <id> or --organization <id>","errorType":"console","errorClass":"CommandError","httpStatus":null,"severity":"error","filePath":"label_studio/tasks/management/commands/recalculate_task_counters.py","lineNumber":60,"sourceCode":"            help='Only report how many tasks have drifted counters; do not modify anything',\n        )\n\n    def _drifted_count(self, project):\n        \"\"\"Number of tasks whose cached total_annotations disagrees with the real count.\"\"\"\n        return (\n            Task.objects.filter(project=project)\n            .annotate(real_total=Count('annotations', filter=Q(annotations__was_cancelled=False), distinct=True))\n            .exclude(total_annotations=F('real_total'))\n            .count()\n        )\n\n    def handle(self, *args, **options):\n        project_id = options.get('project')\n        organization_id = options.get('organization')\n        dry_run = options.get('dry_run')\n\n        if not project_id and not organization_id:\n            raise CommandError('Provide --project <id> or --organization <id>')\n\n        if project_id:\n            projects = Project.objects.filter(id=project_id)\n            if not projects.exists():\n                raise CommandError(f'Project {project_id} not found')\n        else:\n            projects = Project.objects.filter(organization_id=organization_id)\n            if not projects.exists():\n                raise CommandError(f'No projects found for organization {organization_id}')\n\n        for project in projects:\n            drifted_before = self._drifted_count(project)\n            self.stdout.write(\n                f'Project {project.id} ({project.title!r}): {drifted_before} task(s) with drifted counters'\n            )\n\n            if dry_run:\n                continue","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/tasks/management/commands/recalculate_task_counters.py#L42-L78","documentation":"The recalculate_task_counters management command recomputes per-project task/annotation counters. It requires an explicit scope: handle() raises Django's CommandError if neither --project nor --organization is given, preventing an accidentally unbounded recount over all projects.","triggerScenarios":"Running `python label_studio/manage.py recalculate_task_counters` without --project <id> or --organization <id> (with or without --dry_run).","commonSituations":"Operator forgetting the scope flag when fixing drifted counters; copy-pasting a command example that omitted scope; running via cron with missing arguments.","solutions":["Run with a project scope: `... recalculate_task_counters --project 12`","Run with an organization scope: `... recalculate_task_counters --organization 1`","Add `--dry_run` first to preview changes before applying","Verify ids exist: wrong ids trigger the follow-up 'Project ... not found' error"],"exampleFix":"// before\npython label_studio/manage.py recalculate_task_counters\n// after\npython label_studio/manage.py recalculate_task_counters --project 12 --dry_run","handlingStrategy":"validation","validationCode":"# Validate args in a wrapper before invoking the command\nimport sys\nargs = sys.argv[1:]\nif '--project' not in args and '--organization' not in args:\n    sys.exit('Usage: manage.py recalculate_task_counters --project <id> | --organization <id> [--dry_run]')","typeGuard":"function hasScope(options) { return Boolean(options.project || options.organization); }","tryCatchPattern":"from django.core.management import call_command\nfrom django.core.management.base import CommandError\ntry:\n    call_command('recalculate_task_counters', project='12', dry_run=True)\nexcept CommandError as e:\n    print(f'Command refused: {e}')  # fix arguments and retry","preventionTips":["Always do a --dry_run first with an explicit --project or --organization","Wrap the command in shell scripts that assert required flags","Never schedule it in cron without scope arguments","Document expected project/organization ids in runbooks"],"tags":["cli","django-management-command","missing-argument","label-studio"],"backgroundTag":"missing-required-argument","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}