Warning: You are browsing the documentation for Symfony 2.1, which is no longer maintained.

Read the updated version of this page for Symfony 5.3 (the current stable version).

repeated Field Type

repeated Field Type

This is a special field “group”, that creates two identical fields whose values must match (or a validation error is thrown). The most common use is when you need the user to repeat his or her password or email to verify accuracy.

Rendered as input text field by default, but see type option
Overridden Options
Inherited options
Parent type field
Class Symfony\Component\Form\Extension\Core\Type\RepeatedType

Example Usage

$builder->add('password', 'repeated', array(
    'type' => 'password',
    'invalid_message' => 'The password fields must match.',
    'options' => array('attr' => array('class' => 'password-field')),
    'required' => true,
    'first_options'  => array('label' => 'Password'),
    'second_options' => array('label' => 'Repeat Password'),

Upon a successful form submit, the value entered into both of the “password” fields becomes the data of the password key. In other words, even though two fields are actually rendered, the end data from the form is just the single value (usually a string) that you need.

The most important option is type, which can be any field type and determines the actual type of the two underlying fields. The options option is passed to each of those individual fields, meaning - in this example - any option supported by the password type can be passed in this array.


The repeated field type is actually two underlying fields, which you can render all at once, or individually. To render all at once, use something like:

  • Twig
    {{ form_row(form.password) }}
  • PHP
    <?php echo $view['form']->row($form['password']) ?>

To render each field individually, use something like this:

  • Twig
    {{ form_row(form.password.first) }}
    {{ form_row(form.password.second) }}
  • PHP
    <?php echo $view['form']->row($form['password']['first']) ?>
    <?php echo $view['form']->row($form['password']['second']) ?>


The sub-field names are first and second by default, but can be controlled via the first_name and second_name options.


One of the key features of the repeated field is internal validation (you don’t need to do anything to set this up) that forces the two fields to have a matching value. If the two fields don’t match, an error will be shown to the user.

The invalid_message is used to customize the error that will be displayed when the two fields do not match each other.

Field Options


type: string default: text

The two underlying fields will be of this field type. For example, passing a type of password will render two password fields.


type: array default: array()

This options array will be passed to each of the two underlying fields. In other words, these are the options that customize the individual field types. For example, if the type option is set to password, this array might contain the options always_empty or required - both options that are supported by the password field type.


type: array default: array()

New in version 2.1: The first_options option is new in Symfony 2.1.

Additional options (will be merged into options above) that should be passed only to the first field. This is especially useful for customizing the label:

$builder->add('password', 'repeated', array(
    'first_options'  => array('label' => 'Password'),
    'second_options' => array('label' => 'Repeat Password'),


type: array default: array()

New in version 2.1: The second_options option is new in Symfony 2.1.

Additional options (will be merged into options above) that should be passed only to the second field. This is especially useful for customizing the label (see first_options).


type: string default: first

This is the actual field name to be used for the first field. This is mostly meaningless, however, as the actual data entered into both of the fields will be available under the key assigned to the repeated field itself (e.g. password). However, if you don’t specify a label, this field name is used to “guess” the label for you.


type: string default: second

The same as first_name, but for the second field.

Overridden Options


default: false

Inherited options

These options inherit from the date type:


type: string default: This value is not valid

This is the validation error message that’s used if the data entered into this field doesn’t make sense (i.e. fails validation).

This might happen, for example, if the user enters a nonsense string into a time field that cannot be converted into a real time or if the user enters a string (e.g. apple) into a number field.

Normal (business logic) validation (such as when setting a minimum length for a field) should be set using validation messages with your validation rules (reference).


type: array default: array()

When setting the invalid_message option, you may need to include some variables in the string. This can be done by adding placeholders to that option and including the variables in this option:

$builder->add('some_field', 'some_type', array(
    // ...
    'invalid_message'            => 'You entered an invalid value - it should include %num% letters',
    'invalid_message_parameters' => array('%num%' => 6),


type: boolean

If you wish the field to be ignored when reading or writing to the object, you can set the mapped option to false.

New in version 2.1: The error_mapping option is new to Symfony 2.1.


type: array default: empty

This option allows you to modify the target of a validation error.

Imagine you have a custom method named matchingCityAndZipCode that validates whether the city and zip code match. Unfortunately, there is no “matchingCityAndZipCode” field in your form, so all that Symfony can do is display the error on top of the form.

With customized error mapping, you can do better: map the error to the city field so that it displays above it:

public function setDefaultOptions(OptionsResolverInterface $resolver)
        'error_mapping' => array(
            'matchingCityAndZipCode' => 'city',

Here are the rules for the left and the right side of the mapping:

  • The left side contains property paths.
  • If the violation is generated on a property or method of a class, its path is simply “propertyName”.
  • If the violation is generated on an entry of an array or ArrayAccess object, the property path is [indexName].
  • You can construct nested property paths by concatenating them, separating properties by dots. For example: addresses[work].matchingCityAndZipCode
  • The left side of the error mapping also accepts a dot ., which refers to the field itself. That means that any error added to the field is added to the given nested field instead.
  • The right side contains simply the names of fields in the form.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.