- 📝 Err.Description is the readable string attached to the current VBA Err object, while Err.Number is the numeric identifier that code should use for branching and recovery.
- ⚙️ Microsoft documents the property as read/write, so VBA can return a built-in message or carry a custom description supplied through Err.Raise.
- ➗ A verified divide-by-zero example produces error 11 in VBA, making the pair “11” plus “Division by zero” more useful than either value alone.
- ⚠️ Our verification found a subtle failure point: executing a new On Error statement resets the Err object, so error values should be copied before another error-handling directive or risky call changes them.
- 🛡️ The safest production pattern is to capture Number, Description, and Source immediately, handle only errors you truly understand, and re-raise unexpected failures with preserved context.
- 💻 Microsoft’s 2026 Office Scripts guidance expands cloud automation, but the reviewed documentation does not announce the removal of desktop VBA, so robust VBA error handling remains relevant for 2027 planning.
I use Err.Description in VBA as the readable message layer of the Err object, and that small string can be the difference between a useful failure report and a cryptic macro stop when automation breaks. Microsoft defines it as a read/write string associated with an error, while the wider Err object stores the number, source, and optional help information that describe the same failure (Microsoft, 2021a; Microsoft, 2021b). For developers learning the difference between syntax, runtime, and logic failures, our basic coding concepts guide provides the broader debugging foundation.
The property matters because VBA error handling is stateful. The Err object represents the most recent runtime error, not a permanent log. A new error can overwrite it, an On Error statement resets it under the current VBA specification, and several control-flow statements clear its properties automatically (Microsoft, 2025; Microsoft, 2021b). That means a good handler must read the error at the right moment. This guide shows exactly what the description contains, how it differs from Err.Number, how to use Err.Raise and Err.Clear, where Err.Source fits, and what can go wrong in real Excel macros.
What the Description Property Actually Returns
When a runtime error occurs, VBA fills the intrinsic Err object with information from Visual Basic, the host application, an accessed object, or code that explicitly raises an error. Err.Description returns the short human-readable description associated with that current error. The value can also be assigned directly because the property is read/write, although Microsoft recommends Raise when code is intentionally generating an error because Raise can populate richer context in one operation (Microsoft, 2021a; Microsoft, 2022a).
A simple divide-by-zero example shows the relationship. Microsoft lists “Division by zero” as VBA error 11 (Microsoft, 2022b). The number is useful for logic because it is stable enough to test, while the text is useful for people because it says what happened.
Sub DemoErrDescription()
On Error GoTo ErrorHandler
Dim result As Double
result = 10 / 0
Exit Sub
ErrorHandler:
MsgBox “Error ” & Err.Number & “: ” & Err.Description
End Sub
In this case the handler can display a message such as “Error 11: Division by zero.” That is already better than logging only the number. It is also better than relying only on the message, because two different error sources can sometimes produce text that is similar enough to confuse automated recovery logic.
| Err member | What it carries | Best use | Important caution |
| Number | Numeric error identifier | Branching, Select Case logic, expected-error handling | Microsoft advises using Number, not the descriptive fields, for programmatic decisions. |
| Description | Readable error message | User messages, logs, diagnostics | It describes only the current Err state and can be overwritten or reset. |
| Source | Object, application, project, or class that generated the error | Diagnostics and richer logs | Standard-module errors may show only the project name unless code supplies more context. |
| HelpFile / HelpContext | Optional help-file path and topic identifier | Legacy context-sensitive help | Often unused in modern Office solutions, but still part of Err. |
| Clear | Method that resets all Err properties | Explicit cleanup after deferred handling | Some statements clear Err automatically, so explicit clearing is not always required. |
| Raise | Method that generates a runtime error | Custom errors and propagation | Preserve original values before raising another error. |
Err.Number Versus the Human-Readable Message
Err.Number and the descriptive message answer different questions. Number answers “which error is this?” Description answers “how should a person understand it?” Microsoft’s Source documentation goes further and cautions that Err properties other than Number should not normally drive program logic. Their main value is richer information for the user or diagnostic record (Microsoft, 2021c).
That distinction prevents a common design mistake: comparing message strings in an If statement. Message text is easier to change, localize, or replace with a custom value. A numeric test such as `If Err.Number = 11 Then` is more appropriate when the handler knows how to recover from division by zero. The message can then be displayed or logged without becoming the condition that decides what code does next.
A safer pattern for expected and unexpected failures
ErrorHandler:
Dim errNum As Long
Dim errDesc As String
Dim errSource As String
errNum = Err.Number
errDesc = Err.Description
errSource = Err.Source
Select Case errNum
Case 11
MsgBox “Cannot divide by zero.”
Case Else
Err.Raise errNum, errSource, errDesc
End Select
The important move is the capture at the top. Once the values are copied into local variables, the handler can call other procedures, write to a log, or prepare a user message without depending on the global Err state remaining unchanged. Attila Tarpai’s 2024 investigation of VBA runtime behavior describes the same call-stack principle: raised and runtime errors search for an enabled handler, and unhandled failures bubble outward rather than becoming a modern structured exception object with a built-in stack trace (Tarpai, 2024).
How Err.Raise Creates Better Custom Errors
For user-defined failures, Err.Raise is usually the right tool. Its arguments let code provide a number, source, description, help file, and help context. Microsoft reserves 0 through 512 for system errors and documents the higher range for user-defined errors, with `vbObjectError` commonly added to an application-specific number (Microsoft, 2022a).
Err.Raise vbObjectError + 1000, _
“FinanceImport.Validator”, _
“Unable to connect to the database.”
After this call, the current description is “Unable to connect to the database.” The value is useful because it explains the business-level failure rather than exposing only a generic application-defined error. The Source value adds another layer of context. Microsoft recommends a `project.class` form for class modules, while standard-module failures may default to the project name (Microsoft, 2021c).
In Excel automation, this becomes especially valuable when one macro performs several operations that can fail for different reasons: opening a workbook, refreshing data, recalculating formulas, exporting a file, or calling another Office application. Our recent Application.Calculate in VBA analysis shows how even a familiar Excel operation benefits from explicit failure boundaries.
The practical rule is to raise only errors that actually represent a failure boundary. Do not use errors as ordinary branching. Validate obvious conditions with If statements first, then reserve Raise for states the caller should treat as exceptional.
What Err.Clear Does, and When It Is Necessary
Err.Clear resets all property settings in the Err object. Microsoft specifically recommends it after an error has been handled when code uses deferred handling with `On Error Resume Next`. The same documentation notes that several statements clear Err automatically, including Resume, Exit Sub, Exit Function, Exit Property, and any On Error statement (Microsoft, 2021d).
This creates an easy-to-miss trap. A developer may enter a handler, issue `On Error Resume Next` to protect a logging statement, and only then read the original error. Under VBA’s current specification, the On Error statement resets the Err object (Microsoft, 2025). The result can be a blank description and a zero number. The safer sequence is capture first, then change error-handling mode.
ErrorHandler:
Dim n As Long, d As String, s As String
n = Err.Number
d = Err.Description
s = Err.Source
On Error Resume Next
LogError n, d, s
On Error GoTo 0
This detail is one of the most important findings in the research because it explains many “why did my error disappear?” reports. It also illustrates why good debugging starts with exact evidence. The same discipline is central to our guide on how to debug code with AI, where exact error evidence comes before proposed fixes.
Choosing the Right VBA Error-Handling Pattern
VBA gives developers several ways to respond to failure, but they are not interchangeable. The best choice depends on whether the error is expected, whether execution can safely continue, and whether the current procedure has enough information to recover.
| Pattern | Best fit | Strength | Main risk |
| On Error GoTo ErrorHandler | A procedure with one clear cleanup or reporting path | Centralizes failure handling and keeps normal flow readable | A broad handler can hide which operation failed if the procedure is too large. |
| On Error Resume Next + immediate Err check | A narrow call where one specific failure is expected | Keeps handling close to the risky operation | Ignoring Err after the call silently converts failures into bad state. |
| Err.Raise to the caller | A lower-level procedure cannot responsibly recover | Preserves separation of responsibilities | Re-raising after Err has changed can lose the original context. |
| Pre-validation without raising | Known invalid input or ordinary business rules | Avoids using exceptions as flow control | Validation cannot predict every runtime or object-model failure. |
For most Excel macros, `On Error GoTo ErrorHandler` is the clearest default. Use `Resume Next` only around a small operation whose failure is deliberately being probed, then test Err immediately. Microsoft’s On Error documentation makes the same point for object access: immediate checking removes ambiguity about which interaction produced the error (Microsoft, 2021b).
The design also matters for spreadsheet reliability. Formula errors, missing data, and macro errors can interact, but they are not the same failure layer. A worksheet formula may return `#N/A` while the VBA procedure itself remains healthy. Our spreadsheet formulas guide covers the worksheet layer in more detail, which helps separate formula-state problems from VBA runtime failures.
Risks and Trade-Offs in Real VBA Projects
Stale or overwritten error state
Because Err is global and represents the latest error, a second failure can overwrite the first. That is why logging routines should receive copied values as arguments instead of reading Err deep inside another procedure. The same rule applies before calling code that may raise an error during cleanup.
Generic descriptions that help nobody
A custom message such as “Operation failed” is technically valid but operationally weak. Good descriptions name the failed action and, when safe, the relevant object or input: “Could not open the monthly sales workbook” is far more actionable. Avoid embedding secrets, credentials, or sensitive data in messages that may reach logs or screenshots.
Using Resume Next too broadly
`On Error Resume Next` is powerful because execution continues, but that is also its risk. If code performs five object-model calls under one broad Resume Next block and checks Err only at the end, the handler may not know which operation actually failed. Narrow the scope, check immediately, then restore normal handling.
Treating VBA errors like modern exceptions
VBA error handling predates structured Try/Catch systems. It does not give each error an immutable exception object with a native stack trace. The practical workaround is disciplined procedure boundaries, explicit Source values for custom errors, and immediate capture of the current error state.
A Production-Ready Error Handler for Excel
A reusable pattern should preserve context, separate expected errors from unexpected ones, provide a clean exit path, and avoid changing Err before its values are captured. The example below is intentionally small enough to audit.
Sub ImportReport()
On Error GoTo ErrorHandler
‘ Main work goes here.
CleanExit:
Exit Sub
ErrorHandler:
Dim n As Long, d As String, s As String
n = Err.Number
d = Err.Description
s = Err.Source
If n = 53 Then
MsgBox “The required file was not found.”, vbExclamation
Else
MsgBox “Error ” & n & “: ” & d & vbCrLf & “Source: ” & s, vbCritical
End If
Resume CleanExit
End Sub
For larger systems, replace the message box with a logging function that accepts the captured values plus the procedure name, workbook, user action, and timestamp. That produces a useful diagnostic record without assuming Err itself will survive the rest of the handler unchanged.
The Future of VBA Error Handling in 2027
The 2027 outlook is less about the property changing and more about where VBA sits beside newer Excel automation models. Microsoft’s February 2026 Office Scripts documentation continues to position Office Scripts as a way to automate Excel tasks, share scripts, and connect them to Power Automate. Microsoft also distinguishes the two technologies directly: VBA remains focused on desktop solutions, while Office Scripts are designed for cross-platform and cloud-based automation (Microsoft, 2026; Microsoft, n.d.).
That split suggests a practical future rather than a sudden replacement. Desktop workbooks that depend on the Excel object model, events, forms, legacy add-ins, or cross-Office automation will continue to encounter VBA error handling. Cloud workflows will increasingly use TypeScript-based Office Scripts and Power Automate, where error semantics are different. Teams maintaining both should standardize what an error record means across environments: operation, numeric or typed identifier, readable message, source, timestamp, and safe context.
The official documentation reviewed for this article does not announce a 2027 deprecation of VBA or its Err object. That is not a guarantee of permanent support. The near-term decision is simple: do not leave existing VBA macros with fragile error handling because newer automation options exist.
Key Takeaways
- Err.Description gives people the readable meaning of the current VBA error, while Err.Number is the better field for programmatic decisions.
- Capture Number, Description, and Source immediately when a handler starts, before another On Error statement or risky call changes the state.
- Use Err.Raise for deliberate custom failures because it can carry a number, source, description, and optional help metadata together.
- Use Err.Clear deliberately with deferred handling, but remember that VBA also clears or resets Err in several normal control-flow situations.
- Keep `On Error Resume Next` narrow and check Err immediately after the exact operation you expected might fail.
- Treat user-facing error messages as diagnostic UX: precise, safe, and actionable beats generic wording.
- Plan for a mixed 2027 automation environment in which desktop VBA and cloud Office Scripts may coexist rather than assuming one instantly replaces the other.
Conclusion
The description property looks small, but it sits at the human edge of VBA’s entire runtime error model. The number tells code what happened. The message tells a person what happened. The source adds context, Raise lets a procedure create a richer failure, and Clear controls when old state should be discarded.
The most important habit is timing. Read the Err values before doing anything that might reset or overwrite them. Then make a deliberate choice: handle the error, report it, or re-raise it so a caller with more context can decide. That approach scales from a ten-line Excel macro to a large workbook automation project because it preserves evidence instead of guessing after the fact.
VBA may share more automation territory with Office Scripts in 2027, but existing desktop code still needs predictable failure behavior. Clear messages and preserved context are not legacy concerns. They are basic reliability engineering.
FAQ
How does Err.Number differ from Err.Description?
Err.Number is the numeric identifier for the current VBA error and is the better field for program logic. The description is the readable message associated with that error and is best used for logs, diagnostics, or user-facing text. A robust handler often records both because the pair provides machine-friendly identity and human-friendly meaning.
What is the difference between Err.Raise and Err.Clear?
Err.Raise generates a runtime error and can populate its number, source, description, and help fields. Err.Clear does the opposite: it resets the current Err properties. Use Raise when a procedure must signal failure to its caller, and use Clear when deferred handling has finished and stale error state should not affect later checks.
How do I use Err.Source in VBA error handling?
Use Source as diagnostic context showing which object, application, project, or class generated the failure. Microsoft recommends a project.class style for class modules. For your own raised errors, set Source deliberately so logs can distinguish where the failure began. Do not rely on Source text as the primary condition for recovery logic.
What happens if I do not call Err.Clear after an error?
You do not always need to call it manually. Microsoft documents several statements that clear or reset Err automatically, including Resume, procedure exits, and On Error statements. The risk appears when code uses `On Error Resume Next` and later checks Err without a clean boundary. In that pattern, explicit clearing can prevent an old error from being mistaken for a new one.
How do HelpFile and HelpContext work with the Err object?
HelpFile can store the path to a help file, while HelpContext identifies a topic inside it. They support context-sensitive help from an error dialog. These fields are less common in modern Office automation, but they remain part of the Err object and can still be supplied through Err.Raise when a legacy application depends on them.
Can Err.Description be set directly?
Yes. Microsoft documents the property as read/write, so code can assign a string directly. For a deliberate application error, however, Err.Raise is usually cleaner because the number, source, description, and optional help information can be created as one coherent error record.
How does VBA error handling relate to Excel formula errors?
They are different layers. A worksheet can contain `#N/A`, `#VALUE!`, or another formula error without raising a VBA runtime error. A macro may also fail while reading or transforming spreadsheet data. For practical examples of cleaning worksheet-level errors before automation, see our Excel data cleaning guide.
Methodology
This article was researched against Microsoft’s official VBA documentation for Description, Err, Source, Raise, Clear, On Error semantics, and error 11. The 2027 section was checked against Microsoft’s current Office Scripts overview and its published comparison of Office Scripts with VBA macros. A 2024 independent runtime analysis by Attila Tarpai was used as practitioner context for how errors move through the VBA call stack.
This article was drafted with AI assistance and reviewed by the Perplexity AI Editorial Team. All data, citations, and claims have been independently verified against primary sources.
References
Microsoft. (2021a). Description property (Visual Basic for Applications). Microsoft Learn. https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/description-property-visual-basic-for-applications
Microsoft. (2021b). Err object. Microsoft Learn. https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/err-object
Microsoft. (2021c). Source property (Visual Basic for Applications). Microsoft Learn. https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/source-property-visual-basic-for-applications
Microsoft. (2022a). Raise method (Visual Basic for Applications). Microsoft Learn. https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/raise-method
Microsoft. (2022b). Division by zero (Error 11). Microsoft Learn. https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/division-by-zero-error-11
Microsoft. (2021d). Clear method (Visual Basic for Applications). Microsoft Learn. https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/clear-method-visual-basic-for-applications
Microsoft. (2025). [MS-VBAL]: On Error Statement. Microsoft Learn. https://learn.microsoft.com/en-us/openspecs/microsoft_general_purpose_programming_languages/ms-vbal/e2561165-c99a-444b-8bc0-be60a196867a
Microsoft. (2026). Office Scripts in Excel. Microsoft Learn. https://learn.microsoft.com/en-us/office/dev/scripts/overview/excel
Microsoft. (n.d.). Differences between Office Scripts and VBA macros. Microsoft Learn. https://learn.microsoft.com/en-us/office/dev/scripts/resources/vba-differences
Tarpai, A. (2024, February 15). VBA run-time error handling mechanism. VBA Internal Investigations. https://vba-internal-investigations.bblog.halicery.no/2024/02/vba-error-handling-mechanism.html