Fix it now
Error 91 is “Object variable or With block variable not set”. The variable you touched holds nothing, so the line the debugger highlights is not the line that is wrong – the fault is wherever the assignment should have happened and did not. Work backwards from the highlighted line to that point.
- Click Debug and note the object variable on the highlighted line, then find where it should have been given a value.
- Check that the assignment uses Set. Assigning an object without it is the single most common cause: it is Set ws = Worksheets(“Data”), never ws = Worksheets(“Data”).
- Put Option Explicit at the top of every module, then run Debug > Compile to find every undeclared name in one pass.
- If the variable comes from a search or a lookup, test the result before using it. Find and its relatives return Nothing when they do not match, and Nothing is what produces this error one line later.
- Set a breakpoint just above the failing line, run to it, and type ?TypeName(yourVariable) in the Immediate window. Nothing means the assignment never happened; anything else means it happened and something released it.
A With block behaves the same way. It evaluates its expression once, so if that expression yields Nothing every line inside the block fails – which is why the published message names both cases.
If the procedure runs through, you are done. The next section explains what VBA is actually doing when it raises 91, and how the neighbouring numbers differ.
Why it happens
An object variable is a pointer with a type attached. Declaring it reserves the variable and leaves it empty; only Set gives it something to point at. Member access on that variable is resolved at run time against whatever it currently references, so an empty variable produces a member access against nothing at all. That is error 91, and Microsoft’s published message – “Object variable or With block variable not set” – names the two places it happens.
The neighbouring numbers describe the same family of mistakes at slightly different points, and Microsoft publishes a short message for each. 424 is “Object required”: the thing on the left of the dot is not an object at all, which is what a misspelled name produces in a module without Option Explicit, because VBA quietly invents a Variant for you. 438 is “Object doesn’t support this property or method”: the object is real and the member is not, which is what late binding gives you when the code assumes a type the object does not have.
Two more sit at the edges of the group. 94 is “Invalid use of Null”, which has nothing to do with objects: it is a Null from a database field being put into a variable that cannot hold one, which is why it shows up in Access code far more than anywhere else. 449 is “Argument not optional or invalid property assignment” and 450 is “Wrong number of arguments or invalid property assignment” – note that both of those carry a second half about property assignment, so a procedure signature is not the only thing that raises them.
The Set keyword is missing
You have this one if The assignment line looks right, has no Set, and the error is raised on the first line that uses the variable rather than on the assignment.
- Add Set to every assignment of an object reference.
- Remember the reverse rule: Set must not be used when assigning a value such as a number or a string.
- Run Debug > Compile before running anything, which catches the obvious cases without executing them.
A lookup returned Nothing and the code used it anyway
You have this one if The macro works on most files and fails on one, and the failing line follows a Find, a Match or a lookup in a collection.
- Assign the result to a variable, then test it with Is Nothing before using it.
- Handle the not-found case explicitly rather than assuming the search always succeeds.
- For a lookup by name in a collection, trap the error or iterate and compare, because a missing key raises rather than returning Nothing.
The variable was never declared, or declared too loosely
You have this one if 424, or a variable that mysteriously holds Empty, in a module without Option Explicit.
- Add Option Explicit to every module, and switch on Require Variable Declaration in the editor’s options so new modules get it.
- Compile and fix every undeclared name the compiler reports.
- Declare object variables with a specific type where you can, so the editor checks members at compile time rather than at run time.
The object is gone, or never had that member
You have this one if 438, or a 91 on a variable that was definitely assigned earlier in the same procedure.
- Check whether something closed the workbook, document or form the variable pointed at. Closing an object invalidates every reference to it.
- Read the actual type at run time with ?TypeName(obj) in the Immediate window and compare it with what the code assumes.
- For late-bound code, confirm the member exists on that version of the object model.
- Stop reusing one variable for objects of different types across a long procedure.
A database field returned Null
You have this one if 94, in Access or in code reading a recordset, on a line assigning a field value into a String or a numeric variable.
- Test the field with IsNull before assigning it, or coerce it by concatenating an empty string.
- Declare the receiving variable as Variant where Null is a legitimate value.
- Set a default at the table level if the field should never have been Null in the first place.
Full reference
The shape every lookup should have
Dim ws As Worksheet
Dim hit As Range
Set ws = ThisWorkbook.Worksheets("Data")
Set hit = ws.Columns("A").Find(What:="Invoice", LookAt:=xlWhole)
If hit Is Nothing Then
MsgBox "No matching row found.", vbInformation
Exit Sub
End If
MsgBox "Found at " & hit.Address
Three things in that block do the work: an explicit worksheet variable so nothing depends on what is active, Set on both assignments, and an Is Nothing test between the search and the first use of its result. Nearly every 91 in real code is one of those three missing.
Reading the number
| Error | Published message | Typical trigger |
|---|---|---|
| 91 | Object variable or With block variable not set | An object variable used before Set assigned it anything |
| 424 | Object required | The item before the dot is not an object, often a misspelled name |
| 438 | Object doesn’t support this property or method | The object exists and has no member of that name |
| 449 | Argument not optional or invalid property assignment | A required argument missing, or a property assigned wrongly |
| 450 | Wrong number of arguments or invalid property assignment | The wrong number of arguments, or a property assigned as if it were a method |
| 94 | Invalid use of Null | A Null assigned to a variable that cannot represent one |
Making the debugger tell you the truth
- Set Error Trapping to Break on All Errors while you diagnose, so nothing further up swallows the failure.
- Watch the object variables in the Locals window as you step with F8; the moment one shows Nothing is the moment before the error.
- Use ?TypeName(x) rather than assuming. A variable holding the wrong kind of object produces 438, not 91, and the two are diagnosed differently.
- Comment out any On Error Resume Next on the path before you start. It moves the failure to a later line where the state is already wrong.
Why the same macro fails only for one person
Because their file differs. A missing sheet, a renamed range, a lookup value that is not there, a workbook opened read-only – each makes an assignment fail on their data and not on yours. That is an argument for the Nothing checks rather than against them: with the checks in, the macro tells the user which sheet is missing instead of stopping on a line number they cannot interpret.
When it started after an update
Open the Visual Basic editor and check Tools > References for entries marked MISSING. A broken reference stops the whole project compiling, and the failures that follow often look like object errors because that is the first thing the code touches. Fix the reference before you go looking at the object model.
Every code this article covers
| Code | What it points at | Source |
|---|---|---|
91 |
Object variable or With block variable not set | Microsoft Learn |
424 |
Object required | Microsoft Learn |
438 |
Object doesn’t support this property or method | Microsoft Learn |
450 |
Wrong number of arguments or invalid property assignment | Microsoft Learn |
94 |
Invalid use of Null | Microsoft Learn |
449 |
Argument not optional or invalid property assignment | Microsoft Learn |
Confirm the fix worked
- Run Debug > Compile on the project and confirm it compiles with no errors.
- Step through the failing procedure with F8 and watch each object variable take a value in the Locals window.
- Run the macro against the file that originally failed, not only against your own test file.
- Test the not-found path deliberately by searching for something that is not there, and confirm the code exits cleanly.
- Run it twice in succession without closing the application, to catch state left behind by the first run.
Questions people ask about this
Is there anything to buy to fix this?
No. This costs nothing. These are coding errors, and every tool for finding them – the compiler, the debugger, the Locals and Immediate windows – is part of the Office application you already have.
Why does the macro work for me and fail for a colleague?
Usually because their file differs: a missing sheet, a renamed range or an absent lookup value makes an assignment fail on their data. Add the Is Nothing checks and the macro will report the real problem instead of stopping on error 91.
The error started after an Office update. What changed?
Check Tools > References in the Visual Basic editor for anything marked MISSING. A broken reference stops the whole project compiling, and the resulting failures often look like object errors.
Should I use On Error Resume Next to get past it?
Only around one statement whose failure you genuinely expect, and switch it off again immediately afterwards. Wrapping a whole procedure in it hides the failure and lets the code carry on with wrong data, which is worse than stopping.
What is the difference between 91 and 438?
91 means the variable holds nothing at all. 438 means it holds a real object that has no member of the name you used. The first sends you to the assignment; the second sends you to the object model, or to the version of it that is actually installed.
