[swift] What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?

My Swift program is crashing with EXC_BAD_INSTRUCTION and one of the following similar errors. What does this error mean, and how do I fix it?

Fatal error: Unexpectedly found nil while unwrapping an Optional value

or

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value


This post is intended to collect answers to "unexpectedly found nil" issues, so that they are not scattered and hard to find. Feel free to add your own answer or edit the existing wiki answer.

This question is related to swift exception error-handling

The answer is


I came across this error while making a segue from a table view controller to a view controller because I had forgotten to specify the custom class name for the view controller in the main storyboard.

Something simple that is worth checking if all else looks ok


TL;DR answer

With very few exceptions, this rule is golden:

Avoid use of !

Declare variable optional (?), not implicitly unwrapped optionals (IUO) (!)

In other words, rather use:
var nameOfDaughter: String?

Instead of:
var nameOfDaughter: String!

Unwrap optional variable using if let or guard let

Either unwrap variable like this:

if let nameOfDaughter = nameOfDaughter {
    print("My daughters name is: \(nameOfDaughter)")
}

Or like this:

guard let nameOfDaughter = nameOfDaughter else { return }
print("My daughters name is: \(nameOfDaughter)")

This answer was intended to be concise, for full comprehension read accepted answer


Resources


The errors EXC_BAD_INSTRUCTION and fatal error: unexpectedly found nil while implicitly unwrapping an Optional value appears the most when you have declared an @IBOutlet, but not connected to the storyboard.

You should also learn about how Optionals work, mentioned in other answers, but this is the only time that mostly appears to me.


Basically you tried to use a nil value in places where Swift allows only non-nil ones, by telling the compiler to trust you that there will never be nil value there, thus allowing your app to compile.

There are several scenarios that lead to this kind of fatal error:

  1. forced unwraps:

    let user = someVariable!
    

    If someVariable is nil, then you'll get a crash. By doing a force unwrap you moved the nil check responsibility from the compiler to you, basically by doing a forced unwrap you're guaranteeing to the compiler that you'll never have nil values there. And guess what it happens if somehow a nil value ends in in someVariable?

    Solution? Use optional binding (aka if-let), do the variable processing there:

    if user = someVariable {
        // do your stuff
    }
    
  2. forced (down)casts:

    let myRectangle = someShape as! Rectangle
    

    Here by force casting you tell the compiler to no longer worry, as you'll always have a Rectangle instance there. And as long as that holds, you don't have to worry. The problems start when you or your colleagues from the project start circulating non-rectangle values.

    Solution? Use optional binding (aka if-let), do the variable processing there:

    if let myRectangle = someShape as? Rectangle {
        // yay, I have a rectangle
    }
    
  3. Implicitly unwrapped optionals. Let's assume you have the following class definition:

    class User {
        var name: String!
    
        init() {
            name = "(unnamed)"
        }
    
        func nicerName() {
            return "Mr/Ms " + name
        }
    }
    

    Now, if no-one messes up with the name property by setting it to nil, then it works as expected, however if User is initialized from a JSON that lacks the name key, then you get the fatal error when trying to use the property.

    Solution? Don't use them :) Unless you're 102% sure that the property will always have a non-nil value by the time it needs to be used. In most cases converting to an optional or non-optional will work. Making it non-optional will also result in the compiler helping you by telling the code paths you missed giving a value to that property

  4. Unconnected, or not yet connected, outlets. This is a particular case of scenario #3. Basically you have some XIB-loaded class that you want to use.

    class SignInViewController: UIViewController {
    
        @IBOutlet var emailTextField: UITextField!
    }
    

    Now if you missed connecting the outlet from the XIB editor, then the app will crash as soon as you'll want to use the outlet. Solution? Make sure all outlets are connected. Or use the ? operator on them: emailTextField?.text = "[email protected]". Or declare the outlet as optional, though in this case the compiler will force you to unwrap it all over the code.

  5. Values coming from Objective-C, and that don't have nullability annotations. Let's assume we have the following Objective-C class:

    @interface MyUser: NSObject
    @property NSString *name;
    @end
    

    Now if no nullability annotations are specified (either explicitly or via NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END), then the name property will be imported in Swift as String! (an IUO - implicitly unwrapped optional). As soon as some swift code will want to use the value, it will crash if name is nil.

    Solution? Add nullability annotations to your Objective-C code. Beware though, the Objective-C compiler is a little bit permissive when it comes to nullability, you might end up with nil values, even if you explicitly marked them as nonnull.


I had this error once when I was trying to set my Outlets values from the prepare for segue method as follows:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // This line pops up the error
            destination.nameLabel.text = item.name
        }
    }
}

Then I found out that I can't set the values of the destination controller outlets because the controller hasn't been loaded or initialized yet.

So I solved it this way:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // Created this method in the destination Controller to update its outlets after it's being initialized and loaded
            destination.updateView(itemData:  item)
        }
    }
}

Destination Controller:

// This variable to hold the data received to update the Label text after the VIEW DID LOAD
var name = ""

// Outlets
@IBOutlet weak var nameLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    nameLabel.text = name
}

func updateView(itemDate: ObjectModel) {
    name = itemDate.name
}

I hope this answer helps anyone out there with the same issue as I found the marked answer is great resource to the understanding of optionals and how they work but hasn't addressed the issue itself directly.


Since the above answers clearly explains how to play safely with Optionals. I will try explain what Optionals are really in swift.

Another way to declare an optional variable is

var i : Optional<Int>

And Optional type is nothing but an enumeration with two cases, i.e

 enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none 
    case some(Wrapped)
    .
    .
    .
}

So to assign a nil to our variable 'i'. We can do var i = Optional<Int>.none or to assign a value, we will pass some value var i = Optional<Int>.some(28)

According to swift, 'nil' is the absence of value. And to create an instance initialized with nil We have to conform to a protocol called ExpressibleByNilLiteral and great if you guessed it, only Optionals conform to ExpressibleByNilLiteral and conforming to other types is discouraged.

ExpressibleByNilLiteral has a single method called init(nilLiteral:) which initializes an instace with nil. You usually wont call this method and according to swift documentation it is discouraged to call this initializer directly as the compiler calls it whenever you initialize an Optional type with nil literal.

Even myself has to wrap (no pun intended) my head around Optionals :D Happy Swfting All.


This is more of a important comment and that why implicitly unwrapped optionals can be deceptive when it comes to debugging nil values.

Think of the following code: It compiles with no errors/warnings:

c1.address.city = c3.address.city

Yet at runtime it gives the following error: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Can you tell me which object is nil?

You can't!

The full code would be:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c3 = BadContact()

        c1.address.city = c3.address.city // compiler hides the truth from you and then you sudden get a crash
    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct BadContact {
    var address : Address!
}

struct Address {
    var city : String
}

Long story short by using var address : Address! you're hiding the possibility that a variable can be nil from other readers. And when it crashes you're like "what the hell?! my address isn't an optional, so why am I crashing?!.

Hence it's better to write as such:

c1.address.city = c2.address!.city  // ERROR:  Fatal error: Unexpectedly found nil while unwrapping an Optional value 

Can you now tell me which object it is that was nil?

This time the code has been made more clear to you. You can rationalize and think that likely it's the address parameter that was forcefully unwrapped.

The full code would be :

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c2 = GoodContact()

        c1.address.city = c2.address!.city
        c1.address.city = c2.address?.city // not compile-able. No deceiving by the compiler
        c1.address.city = c2.address.city // not compile-able. No deceiving by the compiler
        if let city = c2.address?.city {  // safest approach. But that's not what I'm talking about here. 
            c1.address.city = city
        }

    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct GoodContact {
    var address : Address?
}

struct Address {
    var city : String
}

First, you should know what an Optional value is. You can step to The Swift Programming Language for detail.

Second, you should know the optional value has two statuses. One is the full value, and the other is a nil value. So before you implement an optional value, you should check which state it is.

You can use if let ... or guard let ... else and so on.

One other way, if you don't want to check the variable state before your implementation, you can also use var buildingName = buildingName ?? "buildingName" instead.


If you get this error in CollectionView try to create CustomCell file and Custom xib also.

add this code in ViewDidLoad() at mainVC.

    let nib = UINib(nibName: "CustomnibName", bundle: nil)
    self.collectionView.register(nib, forCellWithReuseIdentifier: "cell")

This question comes up ALL THE TIME on SO. It's one of the first things that new Swift developers struggle with.

Background:

Swift uses the concept of "Optionals" to deal with values that could contain a value, or not. In other languages like C, you might store a value of 0 in a variable to indicate that it contains no value. However, what if 0 is a valid value? Then you might use -1. What if -1 is a valid value? And so on.

Swift optionals let you set up a variable of any type to contain either a valid value, or no value.

You put a question mark after the type when you declare a variable to mean (type x, or no value).

An optional is actually a container than contains either a variable of a given type, or nothing.

An optional needs to be "unwrapped" in order to fetch the value inside.

The "!" operator is a "force unwrap" operator. It says "trust me. I know what I am doing. I guarantee that when this code runs, the variable will not contain nil." If you are wrong, you crash.

Unless you really do know what you are doing, avoid the "!" force unwrap operator. It is probably the largest source of crashes for beginning Swift programmers.

How to deal with optionals:

There are lots of other ways of dealing with optionals that are safer. Here are some (not an exhaustive list)

You can use "optional binding" or "if let" to say "if this optional contains a value, save that value into a new, non-optional variable. If the optional does not contain a value, skip the body of this if statement".

Here is an example of optional binding with our foo optional:

if let newFoo = foo //If let is called optional binding. {
  print("foo is not nil")
} else {
  print("foo is nil")
}

Note that the variable you define when you use optional biding only exists (is only "in scope") in the body of the if statement.

Alternately, you could use a guard statement, which lets you exit your function if the variable is nil:

func aFunc(foo: Int?) {
  guard let newFoo = input else { return }
  //For the rest of the function newFoo is a non-optional var
}

Guard statements were added in Swift 2. Guard lets you preserve the "golden path" through your code, and avoid ever-increasing levels of nested ifs that sometimes result from using "if let" optional binding.

There is also a construct called the "nil coalescing operator". It takes the form "optional_var ?? replacement_val". It returns a non-optional variable with the same type as the data contained in the optional. If the optional contains nil, it returns the value of the expression after the "??" symbol.

So you could use code like this:

let newFoo = foo ?? "nil" // "??" is the nil coalescing operator
print("foo = \(newFoo)")

You could also use try/catch or guard error handling, but generally one of the other techniques above is cleaner.

EDIT:

Another, slightly more subtle gotcha with optionals is "implicitly unwrapped optionals. When we declare foo, we could say:

var foo: String!

In that case foo is still an optional, but you don't have to unwrap it to reference it. That means any time you try to reference foo, you crash if it's nil.

So this code:

var foo: String!


let upperFoo = foo.capitalizedString

Will crash on reference to foo's capitalizedString property even though we're not force-unwrapping foo. the print looks fine, but it's not.

Thus you want to be really careful with implicitly unwrapped optionals. (and perhaps even avoid them completely until you have a solid understanding of optionals.)

Bottom line: When you are first learning Swift, pretend the "!" character is not part of the language. It's likely to get you into trouble.


Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to exception

Connection Java-MySql : Public Key Retrieval is not allowed How to print an exception in Python 3? ASP.NET Core Web API exception handling Catching FULL exception message How to get exception message in Python properly What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean? what does Error "Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" mean? Argument Exception "Item with Same Key has already been added" The given key was not present in the dictionary. Which key? sql try/catch rollback/commit - preventing erroneous commit after rollback

Examples related to error-handling

must declare a named package eclipse because this compilation unit is associated to the named module Error:Failed to open zip file. Gradle's dependency cache may be corrupt What does 'index 0 is out of bounds for axis 0 with size 0' mean? What's the source of Error: getaddrinfo EAI_AGAIN? Error handling with try and catch in Laravel What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean? Raise error in a Bash script Javascript Uncaught TypeError: Cannot read property '0' of undefined Multiple values in single-value context IndexError: too many indices for array