{"record":{"id":"6dd426628ce628a0","repo":"fullstackhero/dotnet-starter-kit","slug":"channel-not-found-updatechannelcommandhandler","errorCode":null,"errorMessage":"Channel not found.","messagePattern":"Channel not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Chat/Modules.Chat/Features/v1/Channels/UpdateChannel/UpdateChannelCommandHandler.cs","lineNumber":24,"sourceCode":"using Mediator;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace FSH.Modules.Chat.Features.v1.Channels.UpdateChannel;\n\npublic sealed class UpdateChannelCommandHandler(\n    ChatDbContext db,\n    ICurrentUser currentUser)\n    : ICommandHandler<UpdateChannelCommand, Unit>\n{\n    public async ValueTask<Unit> Handle(UpdateChannelCommand cmd, CancellationToken cancellationToken)\n    {\n        ArgumentNullException.ThrowIfNull(cmd);\n        var userId = currentUser.GetUserId();\n        if (userId == Guid.Empty) throw new UnauthorizedException(\"no current user\");\n\n        var channel = await db.Channels.FirstOrDefaultAsync(c => c.Id == cmd.ChannelId, cancellationToken)\n            .ConfigureAwait(false)\n            ?? throw new NotFoundException(\"Channel not found.\");\n\n        channel.RequireAdmin(userId.ToString());\n        channel.Rename(cmd.Name, cmd.Description);\n        channel.SetPrivate(cmd.IsPrivate);\n\n        await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);\n        return Unit.Value;\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":34,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Chat/Modules.Chat/Features/v1/Channels/UpdateChannel/UpdateChannelCommandHandler.cs#L6-L34","documentation":"UpdateChannelCommandHandler throws NotFoundException(\"Channel not found.\") when no ChatChannel with cmd.ChannelId exists in the database (FirstOrDefaultAsync returns null). It is the module's standard 404 for a missing aggregate. Note the same message is also used deliberately to mask authorization failures downstream, so it does not always mean the row is absent.","triggerScenarios":"PUT/POST to the update-channel endpoint with a ChannelId that was deleted, never existed, or is filtered out by the tenant query filter (channel belongs to another tenant).","commonSituations":"Client holding a stale channel id after the channel was deleted; cross-tenant id reuse (channel exists globally but not in the caller's tenant); typo'd or truncated id from client-side state; test fixtures seeding channels into a different tenant.","solutions":["Verify the ChannelId exists: query db.Channels for the id in the same tenant before updating.","Check tenant isolation — confirm the request's tenant header/claim matches the tenant that owns the channel.","Refresh client state: re-fetch the channel list and use a current id.","If the channel should exist, check the DbMigrator/seed ran and the record was not deleted."],"exampleFix":"// before\nawait api.updateChannel({ channelId: staleId, name });\n\n// after\nconst channels = await api.listChannels();\nconst current = channels.find(c => c.id === staleId);\nif (current) await api.updateChannel({ channelId: current.id, name });","handlingStrategy":"validation","validationCode":"const channel = channelsQuery.data?.find(c => c.id === channelId);\nif (!channel) return; // don't call update for unknown channel\nif (channel.tenantId !== currentTenantId) return; // tenant mismatch guard","typeGuard":"function channelExists(id: string | undefined): id is string {\n  return typeof id === \"string\" && id.length > 0 && knownChannelIds.has(id);\n}","tryCatchPattern":"try {\n  await api.updateChannel({ channelId, name });\n} catch (e) {\n  if (e.status === 404) { invalidateChannelsQuery(); showChannelGone(); }\n  else throw e;\n}","preventionTips":["Invalidate channel caches after delete operations.","Re-fetch channels when switching tenants.","Never persist channel ids across workspace switches.","Verify seed data covers the tenant under test."],"tags":["chat","not-found","channel","ef-core"],"backgroundTag":"entity-not-found","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"}