{"record":{"id":"5a52fd52551fdd54","repo":"kgrzybek/modular-monolith-with-ddd","slug":"pricelist-item-for-activation-must-exist","errorCode":null,"errorMessage":"Pricelist item for activation must exist.","messagePattern":"Pricelist item for activation must exist\\.","errorType":"validation","errorClass":"InvalidCommandException","httpStatus":400,"severity":"error","filePath":"src/Modules/Payments/Application/PriceListItems/ActivatePriceListItem/ActivatePriceListItemCommandHandler.cs","lineNumber":23,"sourceCode":"\r\nnamespace CompanyName.MyMeetings.Modules.Payments.Application.PriceListItems.ActivatePriceListItem\r\n{\r\n    internal class ActivatePriceListItemCommandHandler : ICommandHandler<ActivatePriceListItemCommand>\r\n    {\r\n        private readonly IAggregateStore _aggregateStore;\r\n\r\n        public ActivatePriceListItemCommandHandler(IAggregateStore aggregateStore)\r\n        {\r\n            _aggregateStore = aggregateStore;\r\n        }\r\n\r\n        public async Task Handle(ActivatePriceListItemCommand command, CancellationToken cancellationToken)\r\n        {\r\n            var priceListItem = await _aggregateStore.Load(new PriceListItemId(command.PriceListItemId));\r\n\r\n            if (priceListItem == null)\r\n            {\r\n                throw new InvalidCommandException([\"Pricelist item for activation must exist.\"]);\r\n            }\r\n\r\n            priceListItem.Activate();\r\n\r\n            _aggregateStore.AppendChanges(priceListItem);\r\n        }\r\n    }\r\n}","sourceCodeStart":5,"sourceCodeEnd":31,"githubUrl":"https://github.com/kgrzybek/modular-monolith-with-ddd/blob/91c8ef24b4cb6ef558c95d8267fa07d68c7059f8/src/Modules/Payments/Application/PriceListItems/ActivatePriceListItem/ActivatePriceListItemCommandHandler.cs#L5-L31","documentation":"Thrown by ActivatePriceListItemCommandHandler when _aggregateStore.Load(new PriceListItemId(...)) returns null. Activation requires an existing PriceListItem aggregate; a missing item rejects the command with InvalidCommandException (HTTP 400).","triggerScenarios":"Dispatching ActivatePriceListItemCommand with a PriceListItemId that has no aggregate: wrong/empty Guid, item not created, item from a different country/period scope, or aggregate store cannot find the stream.","commonSituations":"Admin console activates an item from a stale list; event-sourcing stream missing or not yet snapshotted; tenant scoping returns nothing.","solutions":["Verify the PriceListItemId exists in the price list before activation.","Check the aggregate store/event stream for the id and its tenant scope.","Pre-check existence in the controller and return 404.","Map InvalidCommandException to 400/404 at the API boundary."],"exampleFix":"// before\nawait _commandDispatcher.SendAsync(new ActivatePriceListItemCommand(itemId));\n\n// after\nvar item = await _priceListQueries.GetItemAsync(itemId);\nif (item is null) return NotFound(\"Price list item not found.\");\nawait _commandDispatcher.SendAsync(new ActivatePriceListItemCommand(itemId));","handlingStrategy":"validation","validationCode":"var item = await _priceListQueries.GetItemAsync(itemId);\nif (item is null) return NotFound(\"Price list item not found.\");\nawait _commandDispatcher.SendAsync(new ActivatePriceListItemCommand(itemId));","typeGuard":"public static bool IsValidItemId(ActivatePriceListItemCommand c) =>\n    c.PriceListItemId != Guid.Empty;","tryCatchPattern":"try { await _commandDispatcher.SendAsync(cmd); }\ncatch (InvalidCommandException ex) when (ex.Errors.Any(m => m.Contains(\"must exist\")))\n{ return NotFound(new { errors = ex.Errors }); }","preventionTips":["Refresh admin price-list grids to drop stale ids.","Verify the aggregate store stream/tenant scope for the id.","Reject empty Guid at the controller."],"tags":["payments","price-list","not-found","invalid-command-exception","command-handler"],"backgroundTag":null,"analyzedSha":"91c8ef24b4cb6ef558c95d8267fa07d68c7059f8","analyzedAt":"2026-08-13T17:18:16.571Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}