Run-time error 91 means VBA reached a property or method call through an object variable that does not currently refer to a valid object. In practice, the variable is usually Nothing, its target was closed or released, a lookup returned no object, a required reference is missing, or execution entered a With block incorrectly. The reliable fix is to identify the object before the dot on the highlighted line, trace every path that should assign it with Set, and test for Nothing before using it.
What “Object variable or With block variable not set” means
Microsoft’s official title for error 91 is Object variable not set. An object variable stores a reference to an object such as a Workbook, Worksheet, Range, document, database recordset, or application object. VBA cannot evaluate a property or method until that reference points to a real object.
As an Amazon Associate I earn from qualifying purchases.
Object variables have two separate steps:
- Declaration: you tell VBA the variable’s type, for example
Dim ws As Worksheet. - Assignment: you attach the variable to an existing object with
Set, for exampleSet ws = ThisWorkbook.Worksheets("Data").
After declaration but before assignment, ws is Nothing. Calling ws.Range("A1") at that point raises error 91. The same error occurs if code deliberately sets ws = Nothing, closes the workbook that ws referenced, or receives Nothing from a failed search.
Recommended Free Tools
Why VBA says the object variable is not set
A declaration was mistaken for an object
This code declares a variable but never gives it a worksheet reference:
#1 Best Overall
Dim ws As Worksheet
Debug.Print ws.Range("A1").Value
The declaration reserves a variable; it does not create or select a worksheet. Add a valid assignment before the first use:
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
Debug.Print ws.Range("A1").Value
A branch skipped the assignment
An object may be assigned in one branch but not another. If a condition, early exit, or error path bypasses the Set statement, later code still sees Nothing. Review every route through the procedure, not just the route that worked during one test.
The object was released or its parent was closed
Set obj = Nothing is a valid way to release a reference, but any later use requires a new assignment. The same principle applies when code closes a workbook, document, connection, or recordset and then tries to use a child object obtained from it.
Free tools Windows power users keep installed
One-click scans. No signup required.
A lookup returned no object
Methods such as Find can legitimately return Nothing when there is no match. A query or collection lookup can have the same result. Test the returned object before reading a property such as Row, Value, or Name.
A required object-library reference is missing
Code that relies on an external object library can behave incorrectly when the project contains a missing reference. The VBA editor marks this as MISSING: in the References list. Resolve that reference before relying on the affected object type or members.
Execution entered a With block in the middle
A With block creates an implicit object context when VBA executes the With line. Jumping into the middle with GoTo, or using the debugger’s Set Next Statement command to land inside it, skips that initialization. Dot-prefixed expressions such as .Range("A1") then have no initialized object and can raise error 91.
Rank #2
How to fix Run-time error 91 step by step
1. Start with the highlighted line
Click Debug when the error dialog appears. VBA highlights the statement where it first noticed the invalid reference. The highlighted statement is not always where the mistake began; it is the first place VBA had to dereference the invalid object.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsFind the object qualifier immediately before the dot. In ws.Range("A1").Value, the qualifier is ws. In rs.Fields(0).Value, it is rs. In a With block, the implicit qualifier is the expression on the With line.
2. Find its declaration and every assignment
Use Find in the VBE to locate the variable’s Dim, Private, or Public declaration and every Set variable = ... statement. Confirm that the assignment executes before the failing line on every possible path.
Dim ws As Worksheet
If UseArchive Then
Set ws = ThisWorkbook.Worksheets("Archive")
Else
Set ws = ThisWorkbook.Worksheets("Data")
End If
Debug.Print ws.Range("A1").Value
If one branch lacks a Set, add the correct object or exit with a useful message rather than allowing execution to continue with Nothing.
3. Use the correct workbook and worksheet
When working in Excel, qualify objects explicitly. ThisWorkbook means the workbook containing the VBA project; ActiveWorkbook means whichever workbook is active at that instant. If a macro opens another workbook or the user clicks a different window, relying on the active workbook can produce an unexpected target or a failed lookup.
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Data")
ws.Range("A1").Value = "Ready"
Check the exact sheet name, including spaces and punctuation. If the sheet can be renamed or absent, handle that condition before assigning it.
4. Guard a Find or other lookup result
Never use a returned object until you know the lookup succeeded. This pattern handles a missing match safely:
Dim hit As Range
Set hit = ws.Columns(1).Find(What:="ABC", LookAt:=xlWhole)
If hit Is Nothing Then
MsgBox "ABC was not found."
Exit Sub
End If
Debug.Print hit.Row
The test must occur before hit.Row, hit.Address, or any other member access. Apply the same approach to functions that return documents, controls, recordsets, or custom objects.
5. Look for code that sets the variable to Nothing
Search for Set variable = Nothing, cleanup labels, and error handlers. If the procedure can run again after cleanup, reacquire the object before the next operation:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Set rs = Nothing
' A later operation needs a new recordset
Set rs = OpenCustomerRecordset()
If rs Is Nothing Then
MsgBox "The customer query returned no recordset."
Exit Sub
End If
Also inspect parent objects. A range held from a workbook that has been closed is not a safe target for later work; reopen or reacquire the workbook and its child objects.
6. Resolve missing references
Open the Visual Basic Editor with Alt+F11, then choose Tools > References. Look for an entry beginning with MISSING:.
- Record which library is missing so you understand which declarations or members depend on it.
- If the project requires that library, browse to the correct installed version or select it from the list.
- If the project no longer uses it, clear the check box and replace affected declarations with an available library or late-bound type where appropriate.
- Choose Debug > Compile VBAProject and fix compile errors before running again.
Do not randomly check similarly named libraries. A reference should match the object model the project was written to use, and library availability can differ between Office installations.
Rank #4
7. Repair With-block control flow
Put the complete object expression on the With line and enter the block normally:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →With ThisWorkbook.Worksheets("Data")
.Range("A1").Value = "Ready"
.Range("A2").Value = Date
End With
Remove GoTo jumps that land between With and End With. During debugging, restart the procedure or set the next statement to the With line itself, not to an interior line. If control flow is complicated, replace the implicit block with an explicit variable:
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
ws.Range("A1").Value = "Ready"
8. Step through the procedure and inspect state
Press F8 to execute one statement at a time. Stop immediately before the failing line and inspect the variable in the Locals window, a Watch expression, or the Immediate window.
Useful Immediate-window checks include:
? TypeName(ws)
? (ws Is Nothing)
? ThisWorkbook.Name
If evaluating ws Is Nothing itself is unsuitable because the variable was never declared as an object, return to the declaration and compile the project. Confirm that the expected workbook, sheet, range, or other object exists and that each conditional branch performs its assignment.
9. Capture the original error while debugging
If an error handler hides the first failure, temporarily use a handler that records the error number and description, then re-raises or reports it:
On Error GoTo Failed
' Procedure code here
Exit Sub
Failed:
Debug.Print Err.Number
Debug.Print Err.Description
MsgBox "Error " & Err.Number & ": " & Err.Description
End Sub
Err.Number and Err.Description identify the error generated by VBA or by the called component. Avoid a blanket On Error Resume Next while diagnosing; it can allow the program to continue with an unset object and move the visible failure farther from its cause.
Correct patterns for common Error 91 cases
Worksheet variable declared but not assigned
| Problem | Why it fails | Correct pattern |
|---|---|---|
Dim ws As Worksheet followed by ws.Cells(1, 1) |
The declaration leaves ws as Nothing. |
Set ws = ThisWorkbook.Worksheets("Data") before using ws. |
Set ws = Nothing followed by ws.Name |
The reference was explicitly released. | Reacquire the worksheet or stop before the later use. |
Set hit = ...Find(...) followed by hit.Row |
No match leaves hit as Nothing. |
Use If hit Is Nothing Then and handle the no-match case. |
Object creation and assignment
For objects created by a component, declaration and creation remain separate operations. The variable is not usable until the constructor or factory call succeeds and its result is assigned:
Dim helper As Object
Set helper = CreateObject("Some.Component")
If helper Is Nothing Then
MsgBox "The component could not be created."
Exit Sub
End If
helper.Run
The component name in this example is illustrative; use the class and installation supported by your project. If creation fails because a component is unavailable, fix that installation or reference issue rather than dereferencing the variable.
Recordsets, documents, and application objects
The same rule applies outside Excel. A recordset returned by a query, a document returned by an automation server, or an application object returned by a factory must be checked before calling a method. Close operations and error handlers deserve special attention because they often release these objects before a later cleanup statement runs.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How to tell which repair path applies
| Symptom | Likely state | Repair |
|---|---|---|
| The variable was declared but never assigned. | It is Nothing. |
Add the correct Set statement before first use. |
| The variable worked earlier and fails later. | It was set to Nothing, or its parent object was closed. |
Find the release or close path and reacquire the object afterward. |
The error appeared after code moved into a With block. |
Execution entered the block incorrectly. | Start at the With statement and remove jumps into the block. |
| Compilation or object creation is inconsistent. | A required object library is missing. | Use Tools > References, resolve the MISSING: entry, then compile. |
| A search, lookup, or query returned no object. | The result is Nothing. |
Test with If result Is Nothing and branch before using a member. |
Prevention checklist for VBA object variables
- Prefer explicit types such as
Workbook,Worksheet, andRangewhen the object model is known. The editor can then expose members and the compiler can catch more mistakes. - Keep object acquisition close to the first use, and handle a failed search or lookup immediately rather than passing an unchecked
Nothingvalue to another procedure. - Qualify Excel references with
ThisWorkbookor a deliberately assignedWorkbookvariable instead of depending on the active window. - Keep cleanup and error paths outside
Withblocks, or re-enter the block through itsWithstatement. - In procedures that can run repeatedly, reacquire objects after closing a workbook, document, connection, or recordset.
- Compile the VBA project after changing declarations, references, or control flow. Resolve every missing reference before testing runtime behavior.
- Use meaningful names such as
sourceSheet,resultRange, andcustomerRs; clear names make it easier to locate the qualifier on a highlighted line. - Make no-match and unavailable-object outcomes explicit with a message, return value, or controlled exit. An intentional branch is easier to diagnose than a later error 91.
When error 91 still appears after adding Set
Verify that the assignment itself succeeds
A Set statement can execute against the wrong workbook, a misspelled sheet name, or a function that returns Nothing. Step over the assignment with F8 and inspect the variable immediately afterward. Do not assume that reaching the next line proves the intended object was obtained.
Check scope and lifetime
A module-level variable can retain a stale reference while a local variable is recreated on each call. A procedure may also assign a local variable while the failing line uses a different variable with a similar name. Confirm the declaration’s scope and spelling, and inspect the exact qualifier shown on the highlighted line.
Separate the failing statement
Long chained expressions hide which object is invalid. Break them into explicit variables:
Dim wb As Workbook
Dim ws As Worksheet
Dim cell As Range
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Data")
Set cell = ws.Range("A1")
Debug.Print cell.Value
Step through each assignment. The first variable that is Nothing identifies the repair point, while the later property call merely exposes it.
Bottom line: fix the reference, not the symptom
Error 91 is not a mysterious Excel condition and it is not fixed by repeatedly rerunning the macro. At the highlighted line, one object qualifier is invalid. Declare the variable, assign a real object with Set, guard lookups and factory calls against Nothing, reacquire objects after release or closure, resolve missing references, and enter every With block through its opening statement. Those checks address the actual causes documented for “Object variable not set.”
Quick Recap
As an optional Windows-maintenance shortcut, Outbyte PC Repair can check and address some common system issues, clean temporary and cache files, review settings and vulnerabilities, and record app crashes; it complements antivirus software rather than replacing it, and it cannot repair every VBA crash. It runs on Windows 11, 10, 8, and 7, with a category-based free trial of at least two days followed by a paid subscription.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

