{"record":{"id":"83a8acd9bc784c8e","repo":"elsa-workflows/elsa-core","slug":"either-activitytypename-or-stimulushash-must-be-specified","errorCode":null,"errorMessage":"Either ActivityTypeName or StimulusHash must be specified.","messagePattern":"Either ActivityTypeName or StimulusHash must be specified\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Workflows.Runtime/Handlers/DispatchStimulusCommandHandler.cs","lineNumber":27,"sourceCode":"public class DispatchStimulusCommandHandler(IStimulusSender stimulusSender) : ICommandHandler<DispatchStimulusCommand>\n{\n    public async Task<Unit> HandleAsync(DispatchStimulusCommand command, CancellationToken cancellationToken)\n    {\n        var request = command.Request;\n\n        if (request.ActivityTypeName != null)\n        {\n            await stimulusSender.SendAsync(request.ActivityTypeName, request.Stimulus!, request.Metadata, cancellationToken);\n            return Unit.Instance;\n        }\n\n        if (request.StimulusHash != null)\n        {\n            await stimulusSender.SendAsync(request.StimulusHash!, request.Metadata, cancellationToken);\n            return Unit.Instance;\n        }\n\n        throw new InvalidOperationException(\"Either ActivityTypeName or StimulusHash must be specified.\");\n    }\n}","sourceCodeStart":9,"sourceCodeEnd":29,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Workflows.Runtime/Handlers/DispatchStimulusCommandHandler.cs#L9-L29","documentation":"DispatchStimulusCommandHandler dispatches a stimulus either by activity type name or by a precomputed stimulus hash. If neither ActivityTypeName nor StimulusHash is provided on the request, the handler cannot form a stimulus and throws InvalidOperationException.","triggerScenarios":"Sending a dispatch stimulus request (e.g. via the API or an IDispatchStimulusCommand) with both ActivityTypeName and StimulusHash null/empty — e.g. a workflow caller forwarding a bookmark or payload that omitted both fields.","commonSituations":"API clients building the request payload manually and omitting fields; a null stimulus hash propagated from an upstream bookmark lookup that returned nothing; automation calling the endpoint with an empty body.","solutions":["Provide ActivityTypeName (with any stimulus data) or a StimulusHash on the request before dispatching.","If you expected a hash, verify the upstream value that produced it (e.g. the bookmark's stimulus hash) is non-null and passed through.","Add request validation at the API boundary to reject empty dispatch requests with a clear message."],"exampleFix":"// before\nawait mediator.SendAsync(new DispatchStimulusCommand());\n// after\nawait mediator.SendAsync(new DispatchStimulusCommand { ActivityTypeName = \"HttpEndpoint\", Stimulus = stimulus });","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(request.ActivityTypeName) && string.IsNullOrEmpty(request.StimulusHash))\n    throw new ArgumentException(\"Either ActivityTypeName or StimulusHash must be specified.\");","typeGuard":null,"tryCatchPattern":"try { await mediator.SendAsync(command); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"ActivityTypeName or StimulusHash\")) { return BadRequest(ex.Message); }","preventionTips":["Validate dispatch requests at the API boundary before mediating","Never construct DispatchStimulusCommand without stimulus identifiers","Trace where StimulusHash originates and assert non-null upstream","Model the request so at least one field is required by contract"],"tags":["stimulus","runtime","missing-required-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}