Gutenberg richtext block vaildation failed

The problem in your block is due to the selector value of your emailPlaceholder attribute — you set the value to span.kathyContactFormEmail, but there’s actually no span element with that class in your save() function (or the markup/HTML of the element returned by the function).

What you have though, is an input with kathyContactFormEmail as the class, so you would need to change the emailPlaceholder‘s selector to input.kathyContactFormEmail.

And in addition to that, you should also change the source from html to attribute and set attribute to placeholder like so:

emailPlaceholder: {
    type: 'string',
    source: 'attribute',      // change it from 'html' to 'attribute'
    attribute: 'placeholder', // add add this
    selector: 'input.kathyContactFormEmail'
}

Firstly, because you’re using the attribute with the input’s placeholder, i.e. <input placeholder="{ emailPlaceholder }" />.

And secondly, input elements are self-closing, i.e. <input /> and not <input></input>, hence their innerHTML value is empty.

So html source won’t work with inputs because the block editor will read the attribute value from the inner HTML and yet with an <input /> (or even with <input>foo</input> which is invalid..), the editor will get an empty string.

Additional Issues/Considerations

  1. Instead of using a RichText element for editing the emailPlaceholder attribute, I would use a simple text field, e.g. using TextControl like so:

    <TextControl
        label="Placeholder text"
        value={ emailPlaceholder }
        onChange={ ( val ) => updateEl( 'emailPlaceholder', val ) }
    />
    

    PS: Don’t forget to import or load the component, e.g. const { TextControl } = wp.components;.

    And if you use that component, then you would want to use a div, Fragment (<> and </>) or something other than label to wrap the RichText and TextControl elements, e.g. <div><RichText .../><TextControl .../></div>.

  2. The RichText reference says:

    RichText.Content should be used in the save function of your block
    to correctly save rich text content.

    Therefore, instead of <span className={"kathyContactFormEmailLabelText flexCenterCenter"}>{emailLabel}</span>, you should do:

    <RichText.Content
        tagName="span"
        className="kathyContactFormEmailLabelText flexCenterCenter"
        value={ emailLabel }
    />
    
  3. For string literals or non-dynamic attribute values, you should just use the <attribute>="<value>" syntax, so for example instead of className={'kathyContactForm'}, use className="kathyContactForm". That way, your code will become simpler.

  4. In your edit() function, I don’t know why are you returning an array, i.e. return ([<form>...</form>]), but you should set a unique key prop for each outermost parent element (e.g. if you had <p><b>foo <i>bar</i></b> baz</p>, the outermost parent is p). So for example, you would do return ([<form key="your-key">...</form>]).

    And make sure to use unique keys — the two RichText elements in your edit() function used the same key (“editable”).