fullstackhero/dotnet-starter-kit · error · NotFoundException

Webhook subscription

Error message

Webhook subscription {command.Id} not found.

What it means

TestWebhookSubscription's handler reads the subscription with AsNoTracking and throws NotFoundException when the Id doesn't match any subscription. The lookup is read-only; the error guards the subsequent test delivery, which needs a valid subscription URL, secret, and events.

Solutions

  1. Re-list subscriptions and use a current id before sending a test event.
  2. Confirm the subscription exists in the same tenant as the request context.
  3. If just deleted, recreate the subscription, then test it.
  4. Handle the 404 in the UI by refreshing the list and disabling the test action.

Example fix

// before
await mutateTest(id); // throws 404 if subscription vanished
// after
const sub = subscriptions.find(s => s.id === id);
if (!sub) { refreshList(); return; }
await mutateTest(id);
Defensive patterns

Strategy: validation

Validate before calling

const sub = subscriptions.find(s => s.id === id);
if (!sub) { refreshList(); return; }

Type guard

function isKnownSubscription(id, subs) {
  return subs.some(s => s.id === id);
}

Try / catch

try {
  await testSubscription(id);
} catch (ApiError e) when (e.Status === 404) {
  refreshList();
  notify('Subscription was removed');
}

Prevention

When it happens

Trigger: Calling TestWebhookSubscription for an Id that was deleted, never existed, belongs to another tenant (tenant filter), or whose id string was truncated/misformatted on the client.

Common situations: Clicking 'Send test' in the admin UI while another admin deleted the subscription; testing a subscription created in the dashboard app but requested against a different tenant; automated smoke tests referencing seeded ids after re-seeding.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at src/Modules/Webhooks/Modules.Webhooks/Features/v1/TestWebhookSubscription/TestWebhookSubscriptionCommandHandler.cs:24

using Microsoft.EntityFrameworkCore;
using System.Text.Json;

namespace FSH.Modules.Webhooks.Features.v1.TestWebhookSubscription;

public sealed class TestWebhookSubscriptionCommandHandler(
    WebhookDbContext dbContext,
    IWebhookDeliveryService deliveryService,
    IWebhookSecretProtector secretProtector) : ICommandHandler<TestWebhookSubscriptionCommand, bool>
{
    public async ValueTask<bool> Handle(TestWebhookSubscriptionCommand command, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(command);

        var subscription = await dbContext.Subscriptions
            .AsNoTracking()
            .FirstOrDefaultAsync(s => s.Id == command.Id, cancellationToken)
            .ConfigureAwait(false)
            ?? throw new NotFoundException($"Webhook subscription {command.Id} not found.");

        var testPayload = JsonSerializer.Serialize(new
        {
            eventType = "webhook.test",
            timestamp = TimeProvider.System.GetUtcNow().UtcDateTime,
            message = "This is a test webhook delivery."
        });

        await deliveryService.DeliverAsync(
            subscription.Id,
            subscription.Url,
            secretProtector.Unprotect(subscription.ProtectedSecret),
            "webhook.test",
            testPayload,
            cancellationToken).ConfigureAwait(false);

        return true;
    }

View on GitHub (pinned to 3f2959e683)