Principles
Prevent the error before writing one
The best approach to errors is preventing them from happening. Before you write a message, evaluate if the possibility of error can be avoided altogether.
You can often prevent errors by:
- Using helper text to set expectations about the input
- Choosing a form element that guides correct input (e.g. Time Picker to choose a time)
- Using inline validation to flag issues as they happen
- Displaying inline validation over a page-level error when only one field is affected
You can also consider design and engineering solutions that support recovering silently from potential errors. Ask yourself: how can we automatically guide correct input without leveraging errors? For example, this might mean trimming content in a form field to the expected format rather than displaying an error.
Write the message before choosing the component
It can be tempting to choose the messaging component before authoring the message. Draft the message first, free of UI constraints, then choose a solution that fits.
Match the component choice to the severity and complexity of the message:
|
Component |
Use for |
|---|---|
|
Helper text |
Form field level guidance on what to enter and in what format. |
|
Inline Validation |
Feedback about issues connected to a single field, as they happen (often in real time, on the client side). |
|
Feedback about issues connected to multiple fields that must be resolved before continuing. |
|
|
Callout |
System-level messages that aren’t tied to a single action (connectivity, service status). |
|
High-stakes, blocking errors the user must acknowledge before continuing. |
|
|
Brief, low-stakes feedback tied to a user action (e.g. "Space saved"). |
Be specific
Generic messages are the least useful. Write a distinct message for each case whenever possible. When pointing users at a specific piece of information to address, use real values, like numbers, dates, limits, file names, or IDs.
Rename deployment-config-prod.yaml to 250 characters or less.
The release 2024.3.1 already exists in the Production environment.
Your deployment to web-app-prod timed out after 30 minutes.
This filename is too long.
This release already exists.
Deployment failed.
Always check for “unknown” reasons for errors, as most of them should have a knowable cause. As a last resort, be honest: "Something isn't working on our end. Try again in a few minutes."
Be helpful
When displaying errors, we have an opportunity to build user confidence and use positive framing. If we’re clear about what happened and what steps to follow, people feel empowered to resolve issues by themselves, rather than having to contact customer support.
If we focus on what can be done to resolve, we create positive reinforcement, instead of showcasing lack of reliability, or being judgmental about people’s ability to navigate the product successfully.
Don’t blame the user
Even when the user caused the error, focus on the problem and how to fix, not the mistake. Avoid being judgmental and assigning blame, as it results in a negative user experience in an already frustrating context.
Your computer appears to be offline.
Your session ended. Sign in again to keep working.
You went offline.
You didn't stay signed in.
Be careful with error codes
Only include an error code when the user can act on it. For example, when they’ll quote it to customer support, search for it in our docs, or look it up in a log. Append error codes at the end of the message (in brackets) so they provide the context, and don’t use them at the beginning of the sentence.
We couldn't reach the deployment target. Check that the target is online, then try again. (Error 206)
We couldn’t reach /api/deployments/Deployments-1234 (Error 500)
Error 206: target unreachable
The Octopus Server returned 500 Internal Server Error from /api/deployments/Deployments-1234.
If an error code exists only for our own debugging, omit it from the user-facing message.
Anatomy
Comprehensive error messages have three distinct parts to guide users:
- What happened: the outcome of an error
- The cause (optional): detailed explanation of why the error occurred (only include if it helps to resolve the error)
- How to fix it: actionable step to take to resolve the error
What happened
This is the first part of the message, often in heading format (if the selected component supports this). Communicate the high-level outcome of an error in plain language, focusing on the impact to the user.
Try keeping headings to one sentence. Headings have no full stop at the end of the sentence.
Your variables couldn't be saved
Operation failed: VariableEdit returned 403
The cause
Second part of the message is the underlying cause of the error, and it’s optional. Only include it when it helps the user understand what to do. If explaining the cause adds noise without adding clarity, leave it out.
Complete sentences in this section have a full stop.
You don’t have permission to edit unscoped variables.
Missing permission: VariableEditUnscoped.
How to fix it
In the last part, offer clear and actionable advice on how to remedy the issue. If possible, it should be a one step or one click fix (e.g. clicking “Try again”).
If escalation is the only option, give the user concrete actions: the specific permission level to request, the person to contact, and the documentation to refer to. When referring to help documentation, link to sections explaining the error, not generic pages or the home page.
If there’s one way to resolve the error successfully, consider replacing the what happened heading with the instruction. This approach allows users to resolve common issues more quickly without having to scan lengthy instructions. Complete sentences in this section have a full stop.
Contact your Octopus administrator to request the VariableEditUnscoped permission.
Contact your administrator.
Handling multiple errors
When several form fields have errors at once, we aggregate them into a single message rather than displaying separate messages (multiple error panels across a form).
Displaying an Error Summary at the top of a form helps quickly navigate and address problem areas.
To create this release, make 2 changes:
- Add a release version
- Select a channel
Invalid release version. Invalid channel.
Voice and tone
Use plain language
Use plain English. Avoid internal language, uncommon acronyms, and jargon.
We couldn’t connect to your deployment target.
TentacleCommunicationException encountered during pre-deployment.
Use active voice
We use active voice, as it’s quicker to parse and more direct. There might be cases in error messaging where deliberate use of passive voice helps more thoughtful delivery. When the user caused the error, passive voice can soften a message that would otherwise sound accusatory.
Your changes couldn't be saved.
You didn't save your changes.
Use "we" only when owning mistakes
We refer to ourselves (“we”) only when Octopus genuinely caused the underlying problem. Use this approach when it’s important to highlight whose responsibility it is to take action to resolve.
When it's Octopus's responsibility:
We couldn't generate your report. Try again in a few minutes.
When it's user's responsibility:
Your deployment target is offline. Check the target and try again.
Match tone to severity
Errors range from mild inconvenience to genuine harm. We always match the tone to the impact to the user. As severity rises, humor drops out completely. There’s no room for a playful tone in a serious error, as it reads as dismissive and out of touch.
|
Severity |
Description |
Example |
|---|---|---|
|
Minor |
The user can fix the error themselves, quickly, with no real consequence. |
Your password didn't match. Try again. |
|
Moderate |
The user can fix the error, but it takes effort, another person, or another tool. |
Your role doesn't have permission to deploy to Production. Ask your Octopus administrator to grant you the DeploymentCreate permission for this environment. |
|
Severe |
The user can’t fix it themselves, and the consequences are real: data loss, financial impact, and security implications. |
We couldn't process your subscription renewal. Contact support@octopus.com so we can look into it with you. Your instance will keep running while we sort this out. |
Words to avoid
The words below add stress without adding meaning. When authoring error messaging, consider their replacements:
|
Word |
Reason to avoid |
What to use instead |
|---|---|---|
|
Please |
Adds length without meaning |
Don’t use. |
|
Sorry |
Sounds insincere for minor issues |
Reserve only for serious errors (data loss, major user action needed, genuine Octopus faults). |
|
Invalid |
User-hostile and vague |
Be specific in the description of what went wrong. |
|
Failed, failure |
Catastrophizing |
"Couldn't", "didn't", or describe the outcome of the error. |
|
Wrong, incorrect |
Blames the user |
Describe the expected input. |
|
Forbidden, denied, suspended, blocked |
Hostile |
"You don't have permission to…" |
|
Oops, whoops, hmm, yikes |
Makes light of the user’s frustration |
Describe the situation in plain language. |
|
Error |
States the obvious |
Lead with what happened instead. |