fullstackhero/dotnet-starter-kit · error · NotFoundException

Channel not found.

Error message

Channel not found.

What it means

RestoreChannelCommandHandler looks the channel up with IgnoreQueryFilters() specifically so an archived (soft-deleted) channel can be found, then throws NotFoundException only if no channel with that Id exists at all (including deleted). If the channel exists but isn't deleted, the handler returns idempotently without error.

Solutions

  1. Verify the id exists in the Channels table (including IsDeleted rows) in the current tenant's DB.
  2. Note restore is idempotent — a 404 means the row is truly gone, not already restored.
  3. Use the audit/soft-delete data to confirm the channel was soft- (not hard-) deleted.
  4. Handle the 404 in the archive UI by removing the entry from the list.

Example fix

// before
await api.post(`/channels/${id}/restore`); // assumes it's just archived
// after
try {
  await api.post(`/channels/${id}/restore`);
} catch (e) {
  if (isNotFound(e)) removeFromArchiveList(id); // channel no longer exists at all
  else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const archived = await fetchArchivedChannel(channelId); // must still exist (soft-deleted ok)
if (!archived) throw new Error('Channel no longer exists');

Try / catch

try { ... } catch (e) {
  if (isNotFound(e)) { removeFromArchiveUi(channelId); notify('Channel no longer exists'); }
  else throw e;
}

Prevention

When it happens

Trigger: Restoring a channel id that never existed, was hard-deleted, or belongs to another tenant — even IgnoreQueryFilters can't find it; calling restore on an id mistyped or from a different environment's DB.

Common situations: Archive list out of sync with the DB (channel purged); cross-tenant restore attempt; id taken from an audit log of another environment; duplicate restore after a hard delete by cleanup jobs.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15). Data as JSON: /api/errors/1cf75d124dfd28c4. Report an issue: GitHub.

Appendix: source

Thrown at src/Modules/Chat/Modules.Chat/Features/v1/Channels/RestoreChannel/RestoreChannelCommandHandler.cs:20

using FSH.Modules.Chat.Contracts.v1.Commands;
using FSH.Modules.Chat.Data;
using Mediator;
using Microsoft.EntityFrameworkCore;

namespace FSH.Modules.Chat.Features.v1.Channels.RestoreChannel;

public sealed class RestoreChannelCommandHandler(ChatDbContext db)
    : ICommandHandler<RestoreChannelCommand, Unit>
{
    public async ValueTask<Unit> Handle(RestoreChannelCommand cmd, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(cmd);

        // IgnoreQueryFilters bypasses the SoftDelete filter so we can find an archived channel.
        var channel = await db.Channels.IgnoreQueryFilters()
            .FirstOrDefaultAsync(c => c.Id == cmd.ChannelId, cancellationToken)
            .ConfigureAwait(false)
            ?? throw new NotFoundException("Channel not found.");

        if (!channel.IsDeleted) return Unit.Value; // idempotent
        channel.Restore();
        await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        return Unit.Value;
    }
}

View on GitHub (pinned to 3f2959e683)