{"record":{"id":"e1b53f72fcd3e0b3","repo":"livekit/livekit","slug":"participant-identity-cannot-be-empty","errorCode":null,"errorMessage":"participant identity cannot be empty","messagePattern":"participant identity cannot be empty","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/rtc/errors.go","lineNumber":31,"sourceCode":"// limitations under the License.\n\npackage rtc\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrRoomClosed               = errors.New(\"room has already closed\")\n\tErrParticipantSessionClosed = errors.New(\"participant session is already closed\")\n\tErrPermissionDenied         = errors.New(\"no permissions to access the room\")\n\tErrMaxParticipantsExceeded  = errors.New(\"room has exceeded its max participants\")\n\tErrLimitExceeded            = errors.New(\"node has exceeded its configured limit\")\n\tErrAlreadyJoined            = errors.New(\"a participant with the same identity is already in the room\")\n\tErrDataChannelUnavailable   = errors.New(\"data channel is not available\")\n\tErrDataChannelBufferFull    = errors.New(\"data channel buffer is full\")\n\tErrTransportFailure         = errors.New(\"transport failure\")\n\tErrEmptyIdentity            = errors.New(\"participant identity cannot be empty\")\n\tErrEmptyParticipantID       = errors.New(\"participant ID cannot be empty\")\n\tErrMissingGrants            = errors.New(\"VideoGrant is missing\")\n\tErrInternalError            = errors.New(\"internal error\")\n\n\t// Track subscription related\n\tErrNoTrackPermission         = errors.New(\"participant is not allowed to subscribe to this track\")\n\tErrNoSubscribePermission     = errors.New(\"participant is not given permission to subscribe to tracks\")\n\tErrTrackNotFound             = errors.New(\"track cannot be found\")\n\tErrTrackNotBound             = errors.New(\"track not bound\")\n\tErrSubscriptionLimitExceeded = errors.New(\"participant has exceeded its subscription limit\")\n\n\tErrNoSubscribeMetricsPermission = errors.New(\"participant is not given permission to subscribe to metrics\")\n)\n","sourceCodeStart":13,"sourceCodeEnd":45,"githubUrl":"https://github.com/livekit/livekit/blob/ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6/pkg/rtc/errors.go#L13-L45","documentation":"ErrEmptyIdentity is a validation error from NewParticipant: the ParticipantParams.Identity field is an empty string. LiveKit requires every participant to have a non-empty identity, which is used as its unique user-facing key within a room, so construction is rejected immediately.","triggerScenarios":"Calling rtc.NewParticipant with ParticipantParams.Identity == \"\" (pkg/rtc/participant.go:365), typically when the identity propagated from the join/SignalReceiver request or token grants is missing.","commonSituations":"A client joining with a token minted without the identity claim; upstream service passing an empty user ID into token creation; migration or refactoring dropping the identity assignment before calling NewParticipant.","solutions":["Ensure the join token includes a non-empty identity claim when minting it (AccessToken.SetIdentity).","Validate identity at your API edge (webhook/auth handler) before issuing tokens or creating participants.","Add a guard/log where ParticipantParams is built to catch upstream callers passing empty identity.","If identity is legitimately optional in your product, generate a stable server-side ID (e.g. UUID) as identity."],"exampleFix":"// before\ntoken.AddGrant(&auth.VideoGrant{RoomJoin: true, Room: room})\n// after\ntoken.SetIdentity(userID) // must be non-empty\nif userID == \"\" {\n    return errors.New(\"identity required to join room\")\n}","handlingStrategy":"validation","validationCode":"if identity == \"\" {\n    return fmt.Errorf(\"cannot join room: identity is required\")\n}","typeGuard":"func hasIdentity(params rtc.ParticipantParams) bool {\n    return params.Identity != \"\"\n}","tryCatchPattern":"p, err := rtc.NewParticipant(params)\nif errors.Is(err, rtc.ErrEmptyIdentity) {\n    // reject join request; log token/request that omitted identity\n}","preventionTips":["Always call SetIdentity when minting join tokens","Validate user ID at the auth edge before issuing tokens","Never allow anonymous joins without generating a stable synthetic identity","Add unit tests asserting NewParticipant rejects empty identity"],"tags":["validation","identity","livekit","participant"],"backgroundTag":"missing-required-argument","analyzedSha":"ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6","analyzedAt":"2026-09-02T03:56:08.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}