Error message for a backend constraint

The situation

A designer asked for help with an error message in a flow for creating a digital ad. A user begins the flow by selecting media, then hitting Next to edit the copy. Users can tap Back to return to selecting media, and their copy changes save automatically — except in one circumstance. If there was an error in one of the form fields (such as an invalid character count in the digital ad description), none of the content automatically saves. On iOS, this alert dialog pops up when a user attempts to tap Back with invalid entries.

 

Desktop to mobile backend limitations

My first question was: Is it possible on the backend to save the user’s latest changes, including errors and error states? This way, we could avoid the alert dialog altogether.

It turns out that what appeared as a multi-step flow on mobile originated as a single screen for desktop, and was built that way on the backend. This means that rather than a set of independent steps, the flow validated everything at once all the time — saving errors would break the validation.

Three actions

The error message involves three intertwined sets of actions:

  • Navigating back — The message appears when a user tries to tap Back with invalid entries.

  • Saving or discarding changes — Nowhere else in the flow is the user explicitly saving or discarding content.

  • Fixing errors — The user might not automatically understand the dependency between fixing errors and saving changes.

But which of the actions was primary here? Is the user most interested in going back? Or in preserving their changes?

Header and button label coherence

I also needed to figure out how to align the content of the header with the button labels, and to align the button labels with each other — to create a coherent circuit of options. “Fix” was not a meaningful response to the header “Unable to save changes.” “Fix” was also not a clear alternative to “Discard” in part because they each took different objects: Discard [changes] and Fix [errors].

And how much could we use header and button copy to describe the dependencies, without increasing cognitive load? “To go back, you need to discard changes or save changes. To save changes, you need to fix errors.”

Could we leave any of this implicit — what was the least a user needed to know to get unstuck?

Playground

I worked with the designer and a fellow content designer to brainstorm error messages in which one of the actions was primary. Sometimes we left secondary actions out altogether. We explored CTA options.

 

Knowing that users skim, we didn’t want them to ignore the role that unresolved input errors had on their ability to save changes. If the header read Unable to save changes, and the button label was Save changes they might think “yes, I’d like to save” — not realizing their input errors prevented that. They’d be returned to the form, without further instruction on what to do there. They might hit Back again and read it more closely this time — but do we want to create that kind of friction?

Conclusion

We decided to keep the action of going back implicit in the header, and to frontload the message with the action that was keeping them stuck:

Fix errors first? [in order to continue going back]

We built upon a common mental model: navigating away from a page often requires users to decide between saving or discarding changes. We included direct objects in the button labels to avoid ambiguity, and we used body copy to bridge the gap between two alternative actions. We removed excess language in the body copy that spelled out the dependencies in their entirety.

Correct highlighted errors or your changes will be discarded.

[Discard edits] [Fix errors]

The message aligned with Compass voice and tone guidelines in a circumstance like this — to be direct and invisible. It allowed the design team to finesse a backend problem as painlessly as possible for users.