Response Validation Hook
The ResponseValidationHook is a special built-in hook that runs before OnAfterRespond. It validates that the response outcome and data match the expected schema for the interaction type. Invalid responses are rejected and an error is returned to the client.
Why Response Validation Exists
Without validation, a malicious or buggy client could submit an InteractionResponse with an invalid outcome (e.g., "approved" for a notification type that only accepts "acknowledged") or a malformed data object (e.g., missing required form fields). The validation hook prevents invalid responses from reaching the application.
Built-in Validation Rules
| Type | Valid Outcomes | Required Data Fields |
|---|---|---|
approval | approved, rejected, abstained | None required; comment is optional string |
confirmation | confirmed, cancelled | None |
form | submitted | Validated against the form schema from the payload; required fields must be present |
picker | selected | selectedIds must be a non-empty array of strings from the options list |
notification | acknowledged | None |
What Happens When Validation Fails
Validation Rejects Response
The hook throws InteractionResponseValidationException with a list of validation errors.
Error Ack Sent to Client
The pipeline sends an InteractionAck with status: "error" and the validation error messages to the client's session.
Client Can Retry
The client's respond() promise rejects. The component can show the error and allow the user to correct and resubmit.
Custom Validation for Custom Types
Register a custom validator for your custom interaction types:
// Register a custom type validator
builder.Services.AddInteractionTypeValidator<MyCustomValidator>(
typeKey: "my-company/special-review");
// Implement the validator
public class MyCustomValidator : IInteractionResponseValidator
{
public string TypeKey => "my-company/special-review";
public ValidationResult Validate(
InteractionRequest request,
InteractionResponse response)
{
var validOutcomes = new[] { "approved-with-changes", "approved", "declined" };
if (!validOutcomes.Contains(response.Outcome))
{
return ValidationResult.Failure(
$"Invalid outcome '{response.Outcome}'. Expected one of: {string.Join(", ", validOutcomes)}");
}
if (response.Outcome == "approved-with-changes" && response.Data is null)
{
return ValidationResult.Failure(
"outcome 'approved-with-changes' requires data.changes to be provided.");
}
return ValidationResult.Success();
}
}
Disabling Built-in Validation
ResponseValidationHook is always active and cannot be disabled via configuration. This is intentional — it is a security boundary that prevents invalid responses from reaching application code. If you need to extend validation for a type, add a custom validator; do not bypass the built-in rules.