HumanSignal/label-studio · error · ValidationError

This task cannot be skipped.

Error message

This task cannot be skipped.

What it means

When an annotation is created with was_cancelled=true (i.e. skipping a task), perform_create checks task.can_be_skipped() first. Skipping is only allowed per project annotation settings (e.g. skip enabled for the user's role and within queue/overlap constraints); otherwise a 400 ValidationError with this detail is returned.

Source

Thrown at label_studio/tasks/api.py:1136

            # AnnotationDraft#delete has special behavior (updating created_labels_drafts).
            # This special behavior won't be triggered if we call delete on the queryset.
            # Only for drafts with empty annotation_id, other ones deleted by signal
            draft.delete()
        except AnnotationDraft.DoesNotExist:
            pass

    def perform_create(self, ser):
        task = self.parent_object
        # annotator has write access only to annotations and it can't be checked it after serializer.save()
        user = self.request.user

        # Check if task is being skipped and if it's allowed
        was_cancelled_get = bool_from_request(self.request.GET, 'was_cancelled', False)
        was_cancelled_data = self.request.data.get('was_cancelled', False)
        is_skipping = was_cancelled_get or was_cancelled_data

        if is_skipping and not task.can_be_skipped():
            raise ValidationError({'detail': 'This task cannot be skipped.'})

        # updates history
        result = ser.validated_data.get('result')
        extra_args = {'task_id': self.kwargs['pk'], 'project_id': task.project_id}

        # save stats about how well annotator annotations coincide with current prediction
        # only for finished task annotations
        if result is not None:
            prediction = Prediction.objects.filter(task=task, model_version=task.project.model_version)
            if prediction.exists():
                prediction = prediction.first()
                prediction_ser = PredictionSerializer(prediction).data
            else:
                logger.debug(f'User={self.request.user}: there are no predictions for task={task}')
                prediction_ser = {}
            # serialize annotation
            extra_args.update({'prediction': prediction_ser, 'updated_by': user})

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Enable skipping in Project > Annotation settings (allow skip for the relevant role)
  2. Submit a real annotation instead of a skip (omit was_cancelled)
  3. Reassign the task to a user who is allowed to skip
  4. Adjust `can_be_skipped` conditions (overlap/draft state) if the restriction is unintended

Example fix

// before (skip attempt)
POST /api/tasks/42/annotations/?was_cancelled=true
// after (enable skip in project settings or submit normally)
POST /api/tasks/42/annotations/
{"result": [{"from_name": "label", "type": "choices", "value": {"choices": ["OK"]}}]}
Defensive patterns

Strategy: validation

Validate before calling

// Check skip eligibility client-side before posting a cancelled annotation
const settings = await api.get(`/api/projects/${projectId}/`);
const skipAllowed = settings.skip_type !== undefined && settings.skip_type !== 'None';
if (!skipAllowed || !task.can_be_skipped) {
  // hide/disable the Skip button; do not send was_cancelled=true
}

Type guard

function canSkip(task, projectSettings) {
  return Boolean(projectSettings.allow_skip) && task.can_be_skipped !== false;
}

Try / catch

try {
  await api.post(`/api/tasks/${taskId}/annotations/?was_cancelled=true`, {});
} catch (e) {
  if (e.response?.status === 400 && /cannot be skipped/.test(JSON.stringify(e.response.data))) {
    // prompt a real annotation instead of retrying the skip
  } else throw e;
}

Prevention

When it happens

Trigger: POST to the task annotations endpoint with ?was_cancelled=true or body {"was_cancelled": true} while the project's annotation settings disallow skipping (skip_type/allow_skip disabled for the role or task state forbids it).

Common situations: Annotators pressing 'Skip' in the UI when the project was configured to disallow skips; automation scripts bulk-skipping tasks; overlap fully consumed so no skip slot remains for that user.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/eaae5dd1b9ac5b06. Report an issue: GitHub.