{"record":{"id":"142e8f674152b01d","repo":"fullstackhero/dotnet-starter-kit","slug":"webhook-subscription-command-id-not-found-142e8f","errorCode":null,"errorMessage":"Webhook subscription {command.Id} not found.","messagePattern":"Webhook subscription (.+?) not found\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Webhooks/Modules.Webhooks/Features/v1/TestWebhookSubscription/TestWebhookSubscriptionCommandHandler.cs","lineNumber":24,"sourceCode":"using Microsoft.EntityFrameworkCore;\nusing System.Text.Json;\n\nnamespace FSH.Modules.Webhooks.Features.v1.TestWebhookSubscription;\n\npublic sealed class TestWebhookSubscriptionCommandHandler(\n    WebhookDbContext dbContext,\n    IWebhookDeliveryService deliveryService,\n    IWebhookSecretProtector secretProtector) : ICommandHandler<TestWebhookSubscriptionCommand, bool>\n{\n    public async ValueTask<bool> Handle(TestWebhookSubscriptionCommand command, CancellationToken cancellationToken)\n    {\n        ArgumentNullException.ThrowIfNull(command);\n\n        var subscription = await dbContext.Subscriptions\n            .AsNoTracking()\n            .FirstOrDefaultAsync(s => s.Id == command.Id, cancellationToken)\n            .ConfigureAwait(false)\n            ?? throw new NotFoundException($\"Webhook subscription {command.Id} not found.\");\n\n        var testPayload = JsonSerializer.Serialize(new\n        {\n            eventType = \"webhook.test\",\n            timestamp = TimeProvider.System.GetUtcNow().UtcDateTime,\n            message = \"This is a test webhook delivery.\"\n        });\n\n        await deliveryService.DeliverAsync(\n            subscription.Id,\n            subscription.Url,\n            secretProtector.Unprotect(subscription.ProtectedSecret),\n            \"webhook.test\",\n            testPayload,\n            cancellationToken).ConfigureAwait(false);\n\n        return true;\n    }","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Webhooks/Modules.Webhooks/Features/v1/TestWebhookSubscription/TestWebhookSubscriptionCommandHandler.cs#L6-L42","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait mutateTest(id); // throws 404 if subscription vanished\n// after\nconst sub = subscriptions.find(s => s.id === id);\nif (!sub) { refreshList(); return; }\nawait mutateTest(id);","handlingStrategy":"validation","validationCode":"const sub = subscriptions.find(s => s.id === id);\nif (!sub) { refreshList(); return; }","typeGuard":"function isKnownSubscription(id, subs) {\n  return subs.some(s => s.id === id);\n}","tryCatchPattern":"try {\n  await testSubscription(id);\n} catch (ApiError e) when (e.Status === 404) {\n  refreshList();\n  notify('Subscription was removed');\n}","preventionTips":["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."],"tags":["ef-core","not-found","webhooks","cqrs"],"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"}