{"record":{"id":"42745a314b37a555","repo":"vxcontrol/pentagi","slug":"token-invalidrequest","errorCode":"Token.InvalidRequest","errorMessage":"token with this name already exists","messagePattern":"token with this name already exists","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"backend/pkg/server/services/api_tokens.go","lineNumber":89,"sourceCode":"\t\tlogger.FromContext(c).WithError(err).Errorf(\"error binding JSON\")\n\t\tresponse.Error(c, response.ErrTokenInvalidRequest, err)\n\t\treturn\n\t}\n\tif err := req.Valid(); err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error validating JSON\")\n\t\tresponse.Error(c, response.ErrTokenInvalidRequest, err)\n\t\treturn\n\t}\n\n\tif req.Name != nil && *req.Name != \"\" {\n\t\tvar existing models.APIToken\n\t\terr := s.db.\n\t\t\tWhere(\"user_id = ? AND name = ? AND deleted_at IS NULL\", uid, *req.Name).\n\t\t\tFirst(&existing).\n\t\t\tError\n\t\tif err == nil {\n\t\t\tlogger.FromContext(c).Errorf(\"token with name '%s' already exists for user %d\", *req.Name, uid)\n\t\t\tresponse.Error(c, response.ErrTokenInvalidRequest, errors.New(\"token with this name already exists\"))\n\t\t\treturn\n\t\t}\n\t}\n\n\ttokenID, err := auth.GenerateTokenID()\n\tif err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error generating token ID\")\n\t\tresponse.Error(c, response.ErrInternal, err)\n\t\treturn\n\t}\n\n\tclaims := auth.MakeAPITokenClaims(tokenID, uhash, uid, rid, req.TTL)\n\n\ttoken, err := auth.MakeAPIToken(s.globalSalt, claims)\n\tif err != nil {\n\t\tlogger.FromContext(c).WithError(err).Errorf(\"error signing token\")\n\t\tresponse.Error(c, response.ErrInternal, err)\n\t\treturn","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/server/services/api_tokens.go#L71-L107","documentation":"CreateToken enforces per-user uniqueness of active token names: before generating a token it queries for an existing non-deleted token with the same user_id and name, and if one exists it returns Token.InvalidRequest with 'token with this name already exists'. Names are only unique per user, not globally.","triggerScenarios":"POST /tokens with a body {\"name\": \"X\"} when the same user already owns an active (not soft-deleted) token named X.","commonSituations":"Re-running an automation script that creates tokens idempotently by name; UI double-submit; user forgot an existing token with the same label; retry after a partial failure where the first creation actually succeeded.","solutions":["Choose a different, unique name for the new token.","List existing tokens (GET /tokens) and reuse or rename the existing one instead of creating a duplicate.","Soft-delete the old token with the same name (DELETE /tokens/{id}) then re-create it.","Make the creating script idempotent: look up the token by name first and reuse it on 409/invalid-request."],"exampleFix":"// before\nPOST /tokens {\"name\":\"ci-deploy\"}   // duplicate -> error\n// after\nPOST /tokens {\"name\":\"ci-deploy-2026-09\"}  // unique name succeeds","handlingStrategy":"validation","validationCode":"const names = (await api.get('/tokens')).data.tokens.map(t => t.name).filter(Boolean);\nif (names.includes(desiredName)) throw new Error(`token name '${desiredName}' already in use`);","typeGuard":"function isNameFree(name, existing) { return !existing.some(t => t.name === name); }","tryCatchPattern":"try { await api.post('/tokens', { name }); }\ncatch (e) {\n  if (e.response?.data?.code === 'Token.InvalidRequest' && /already exists/.test(e.response.data.message)) {\n    name = `${name}-${Date.now()}`; // retry with unique suffix\n  } else throw e;\n}","preventionTips":["Check existing token names before creating.","Generate names with timestamps or UUIDs in automation.","Debounce/disable the create button after first submit to avoid double-POSTs.","Remember uniqueness is per-user and ignores soft-deleted tokens."],"tags":["api-tokens","uniqueness","conflict","validation"],"backgroundTag":"duplicate-resource-name","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}