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
- Re-list subscriptions and use a current id before sending a test event.
- Confirm the subscription exists in the same tenant as the request context.
- If just deleted, recreate the subscription, then test it.
- 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
- Only offer the 'send test' action on subscriptions loaded in the current page state.
- Re-fetch the list after any delete/create to keep ids current.
- Check tenant selection before calling webhook endpoints.
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)