{"record":{"id":"66fd162dd32ce492","repo":"fullstackhero/dotnet-starter-kit","slug":"cannot-impersonate-yourself","errorCode":null,"errorMessage":"cannot impersonate yourself","messagePattern":"cannot impersonate yourself","errorType":"exception","errorClass":"CustomException","httpStatus":400,"severity":"warning","filePath":"src/Modules/Identity/Modules.Identity/Features/v1/Impersonation/StartImpersonation/StartImpersonationCommandHandler.cs","lineNumber":77,"sourceCode":"        var actorUserId = _currentUser.GetUserId().ToString();\n        var actorTenantId = _currentUser.GetTenant()\n            ?? throw new UnauthorizedException(\"missing tenant context\");\n        var actorUserName = _currentUser.Name;\n\n        // Cross-tenant impersonation requires the actor to be in the root tenant. Tenant admins\n        // can only impersonate users within their own tenant.\n        if (!string.Equals(actorTenantId, MultitenancyConstants.Root.Id, StringComparison.Ordinal)\n            && !string.Equals(actorTenantId, request.TargetTenantId, StringComparison.Ordinal))\n        {\n            throw new ForbiddenException(\"cross-tenant impersonation is restricted to platform operators\");\n        }\n\n        // Prevent self-impersonation (pointless, confuses the audit trail). Caller error → explicit 4xx,\n        // not the 500 CustomException defaults to.\n        if (string.Equals(actorUserId, request.TargetUserId, StringComparison.Ordinal)\n            && string.Equals(actorTenantId, request.TargetTenantId, StringComparison.Ordinal))\n        {\n            throw new CustomException(\"cannot impersonate yourself\", errors: null, System.Net.HttpStatusCode.BadRequest);\n        }\n\n        // Prevent nesting: if the caller is already impersonating, require end-impersonation first.\n        var callerClaims = _currentUser.GetUserClaims();\n        if (callerClaims is not null\n            && callerClaims.Any(c => c.Type == ClaimConstants.ActorSubject))\n        {\n            throw new CustomException(\n                \"end current impersonation before starting a new one\",\n                errors: null,\n                System.Net.HttpStatusCode.BadRequest);\n        }\n\n        var targetClaimsResult = await _identityService\n            .BuildClaimsForUserAsync(request.TargetUserId, request.TargetTenantId, cancellationToken);\n\n        if (targetClaimsResult is null)\n        {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Identity/Modules.Identity/Features/v1/Impersonation/StartImpersonation/StartImpersonationCommandHandler.cs#L59-L95","documentation":"Self-impersonation (same user id and same tenant) is rejected with CustomException('cannot impersonate yourself', BadRequest) — an explicit 4xx rather than the 500 CustomException defaults to. It is pointless and would pollute the audit trail.","triggerScenarios":"Calling start-impersonation with TargetUserId equal to the caller's own user id and TargetTenantId equal to the caller's tenant.","commonSituations":"A support UI pre-filling the 'current user' as the target by accident; automated tests using the same fixture user for actor and target; copying your own user id from the profile page into the request.","solutions":["Pass a different TargetUserId (the user to impersonate)","Fix the UI/form so the target user cannot default to the signed-in user","Adjust tests to use two distinct users"],"exampleFix":"// before\nconst targetUserId = currentUser.id; // wrong: self\n// after\nconst targetUserId = selectedUser.id; // a different user in the same tenant","handlingStrategy":"validation","validationCode":"if (targetUserId === currentUserId && targetTenantId === currentTenantId) {\n  throw new Error('cannot impersonate yourself: pick a different target user');\n}","typeGuard":null,"tryCatchPattern":"try { await api.startImpersonation(req); }\ncatch (e) { if (e.status === 400 && /yourself/.test(e.message)) { notify('Select a different user to impersonate'); return; } throw e; }","preventionTips":["Disable the current user in target-user pickers","Use distinct actor/target fixtures in tests","Never default the target to the signed-in user"],"tags":["validation","impersonation","bad-request"],"backgroundTag":"invalid-argument-value","analyzedSha":"3f2959e683e9f83f13e55e1678c9119f63c7e8e5","analyzedAt":"2026-09-15T22:20:53.684Z","contentChangedAt":"2026-09-15T22:20:53.684Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}