HumanSignal/label-studio · error · TokenExistsError
token_exists
token_exists
Error message
You already have a valid token. Please revoke it before creating a new one.
What it means
Raised by LSTokenCreateView.perform_create (serializing with code 'token_exists') when the user attempts to create a new API token while still having a valid one. Label Studio enforces a single active token per user; the existing token must be revoked first.
Source
Thrown at label_studio/jwt_auth/views.py:187
# Annoyingly, token_type not stored directly so we have to filter it here.
# Shouldn't be many unexpired tokens to iterate through.
token_objects = list(filter(None, [_maybe_get_token(token) for token in all_tokens]))
refresh_tokens = [tok for tok in token_objects if tok['token_type'] == 'refresh']
serializer = self.get_serializer(refresh_tokens, many=True)
data = serializer.data
return Response(data)
def get_serializer_class(self):
if self.request.method == 'POST':
return LSAPITokenCreateSerializer
return LSAPITokenListSerializer
def perform_create(self, serializer):
# Check for existing valid tokens
existing_tokens = self.get_queryset()
if existing_tokens.exists():
raise TokenExistsError()
token = self.token_class.for_user(self.request.user)
serializer.instance = token
class LSTokenBlacklistView(TokenViewBase):
_serializer_class = 'jwt_auth.serializers.LSAPITokenBlacklistSerializer'
@extend_schema(
tags=['JWT'],
summary='Blacklist a JWT refresh token',
description='Adds a JWT refresh token to the blacklist, preventing it from being used to obtain new access tokens.',
responses={
status.HTTP_204_NO_CONTENT: OpenApiResponse(description='Token was successfully blacklisted'),
status.HTTP_404_NOT_FOUND: OpenApiResponse(
response=TokenDetailErrorSerializer,
description='Token is already blacklisted',
),View on GitHub (pinned to 0b49e9b539)
Solutions
- Delete/revoke the existing token (DELETE /api/sts/tokens/{id} or the blacklist/revoke endpoint) then create the new one
- Reuse the existing valid token instead of minting a new one
- Check for HTTP 409 / code 'token_exists' in clients and revoke before retrying
Example fix
// before POST /api/sts/tokens # fails: token_exists // after DELETE /api/sts/tokens/<existing-id> POST /api/sts/tokens
Defensive patterns
Strategy: try-catch
Validate before calling
const tokens = await fetch('/api/sts/tokens').then(r => r.json());
if (Array.isArray(tokens) && tokens.length > 0) await revokeToken(tokens[0].id); Try / catch
try:
token = create_token(user)
except TokenExistsError:
existing_token = get_valid_token(user)
revoke(existing_token)
token = create_token(user) Prevention
- Always revoke before rotating tokens
- Cache and reuse the existing valid token instead of minting new ones
- Make token rotation idempotent in automation scripts
When it happens
Trigger: POST to the LSAPIToken create endpoint (/api/sts/tokens or similar) when get_queryset() returns at least one existing non-revoked token for the request user.
Common situations: Rotating tokens without first revoking the old one; double-submitting the create-token form; automation scripts that recreate tokens on each run.
Related errors
- Authentication token no longer valid: legacy token authentic
- PermissionDenied
- Invalid Label Studio token
- "file_upload_ids" parameter must be a list of integers
- sample() does not accept arguments.
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/fc0b771a24660e10.
Report an issue: GitHub.