{"record":{"id":"1fd86350e40e4a6a","repo":"fullstackhero/dotnet-starter-kit","slug":"no-current-user-listmyfilesqueryhandler","errorCode":null,"errorMessage":"no current user","messagePattern":"no current user","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"src/Modules/Files/Modules.Files/Features/v1/ListMyFiles/ListMyFilesQueryHandler.cs","lineNumber":27,"sourceCode":"using FSH.Modules.Files.Features.v1.Internal;\nusing Mediator;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace FSH.Modules.Files.Features.v1.ListMyFiles;\n\npublic sealed class ListMyFilesQueryHandler(\n    FilesDbContext db,\n    ICurrentUser currentUser,\n    IStorageService storage)\n    : IQueryHandler<ListMyFilesQuery, ReadOnlyCollection<FileAssetDto>>\n{\n    public async ValueTask<ReadOnlyCollection<FileAssetDto>> Handle(ListMyFilesQuery q, CancellationToken cancellationToken)\n    {\n        ArgumentNullException.ThrowIfNull(q);\n        var userId = currentUser.GetUserId().ToString();\n        if (string.IsNullOrEmpty(userId) || userId == Guid.Empty.ToString())\n        {\n            throw new UnauthorizedException(\"no current user\");\n        }\n\n        var page = Math.Max(1, q.Page);\n        var pageSize = Math.Clamp(q.PageSize, 1, 100);\n\n        var rows = await db.FileAssets.AsNoTracking()\n            .Where(f => f.CreatedByUserId == userId && f.Status == FileAssetStatus.Available)\n            .OrderByDescending(f => f.CreatedAtUtc)\n            .Skip((page - 1) * pageSize)\n            .Take(pageSize)\n            .ToListAsync(cancellationToken)\n            .ConfigureAwait(false);\n\n        // Seed publicUrl for public files so the preview dialog can paint the image\n        // immediately from the list data, without waiting on a metadata refetch to mint it.\n        return rows\n            .Select(f => FileAssetMapper.ToDto(\n                f,","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Files/Modules.Files/Features/v1/ListMyFiles/ListMyFilesQueryHandler.cs#L9-L45","documentation":"ListMyFilesQueryHandler calls currentUser.GetUserId() and rejects the result when it is null/empty or Guid.Empty, throwing UnauthorizedException ('no current user', HTTP 401). The list endpoint is inherently per-user, so an unauthenticated or anonymous principal cannot be served.","triggerScenarios":"Calling the list-my-files endpoint without a valid JWT; an authenticated principal whose id claim is missing/unparseable; anonymous access where the current-user accessor returns Guid.Empty.","commonSituations":"Expired or missing Bearer token in the client; calling the endpoint from a background job or service without user impersonation; auth middleware misconfigured so claims aren't populated; token issued without the user id claim.","solutions":["Attach a valid, unexpired JWT Bearer token to the request","Re-authenticate (refresh/login) if the token expired","Ensure the token contains the user id claim expected by GetUserId()","Don't call this endpoint from non-user contexts — use a user-scoped token or an admin query path"],"exampleFix":"// before\nconst files = await apiFetch('/api/v1/files/mine'); // no auth header\n// after\nconst files = await apiFetch('/api/v1/files/mine', {\n  headers: { Authorization: `Bearer ${await getToken()}` }\n});","handlingStrategy":"try-catch","validationCode":"const token = await getAccessToken();\nif (!token) { redirectToLogin(); }","typeGuard":"const isAuthenticated = (u: User | null): u is User => u !== null && /^[0-9a-f-]{36}$/i.test(u.id) && u.id !== '00000000-0000-0000-0000-000000000000';","tryCatchPattern":"try { const files = await api.listMyFiles(); }\ncatch (e) { if (e.status === 401) { await reauthenticate(); return retry(); } throw e; }","preventionTips":["Attach a valid Bearer token to every files API call","Refresh tokens proactively before expiry","Never call per-user endpoints from service/background contexts without a user token"],"tags":["auth","unauthorized","files","jwt"],"backgroundTag":"authentication-required","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"}