Skip to main content
Validation runs after deserialization and before the result is returned. If the extracted data does not meet your rules, Instructor can automatically retry the request, feeding the validation errors back to the model so it can self-correct.

Symfony Validation Attributes

Instructor uses the Symfony Validator component under the hood. Add constraint attributes to your response model to enforce field-level rules:
If the model returns a name shorter than three characters or a negative age, validation fails and Instructor can retry the request automatically.
For a full list of available constraints, see the Symfony Validation documentation.

Retries

Retries are configured on the runtime, not on individual requests. When validation fails and retries are available, Instructor sends the validation errors back to the model and asks it to try again:
The maxRetries value controls how many additional attempts are allowed after the first one. With maxRetries(3), Instructor will try up to 4 times total (1 initial + 3 retries). If all attempts fail validation, Instructor throws an exception.
In this example, the model might initially return name: "JX" and age: -28. Validation catches both issues, and the retry prompt tells the model what went wrong so it can return name: "Jason" and age: 28 on the next attempt.

Custom Validation With ValidationMixin

For object-level validation logic that goes beyond simple field constraints, use the ValidationMixin trait. Implement a validate() method that returns a ValidationResult:
The ValidationResult class provides several factory methods: When validation fails, Instructor feeds the error messages back to the LLM on retry, just like with Symfony constraints:

Custom Validation With Symfony #[Assert\Callback]

You can also use Symfony’s #[Assert\Callback] attribute directly for full access to the Symfony validation context. This is useful when you want to leverage Symfony’s violation builder API:
See the Symfony Callback constraint docs for more details on the violation builder API.

How Retries Work

When a response fails validation, Instructor:
  1. Collects all validation errors (from Symfony constraints, ValidationMixin, or both).
  2. Formats them into a retry prompt that describes what went wrong.
  3. Appends the retry prompt to the conversation history.
  4. Sends the updated conversation back to the model for another attempt.
This self-correction loop continues until validation passes or the retry limit is reached. The default retry prompt is "JSON generated incorrectly, fix following errors:\n", followed by the list of violations. You can customize it through StructuredOutputConfig: