Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Trailing closure bug?

i am trying to build my code and have ran into this error. "Trailing closure passed to parameter of type 'DispatchWorkItem' that does not accept a closure" i have been trying to figure it out for so long, and even ai cant figure it out. is this a bug, or am i missing some obvious way to fix this ?

func loadUser(uid: String, completion: (() -> Void)? = nil) {
    db.collection("users").document(uid).getDocument { [weak self] snapshot, error in
        guard let data = snapshot?.data(), error == nil else { completion?(); return }
        DispatchQueue.main.async {
            self?.currentUser = User(
                username: data["username"] as? String ?? "Learner",
                email: data["email"] as? String ?? "",
                profileImageName: "person.circle.fill",
                totalXP: data["totalXP"] as? Int ?? 0,
                currentStreak: data["currentStreak"] as? Int ?? 0,
                longestStreak: data["longestStreak"] as? Int ?? 0,
                level: data["level"] as? Int ?? 1,
                levelProgress: data["levelProgress"] as? Double ?? 0.0,
                xpToNextLevel: data["xpToNextLevel"] as? Int ?? 100,
                completedLessons: data["completedLessons"] as? [String] ?? []
            )
            self?.saveUser()
            completion?()
        }
    }
}

Answered by Developer Tools Engineer in 843394022

There are two overloads of DispatchQueue.async—one that takes a () -> Void closure, another that takes a DispatchWorkItem. This error would happen because for some reason the compiler doesn't think the closure is of type () -> Void, so it tries to use the DispatchWorkItem overload instead (but that doesn't work either).

I don't know exactly why the compiler isn't getting the closure type right, but you can force it to do so by changing the closure to look like:

DispatchQueue.main.async { () -> Void in
    // contents of closure as before
}

Once you do that, the compiler should either accept the code, or give you a more specific error message that helps you figure out what the problem is. If you do get a more specific error, you'll probably be able to remove the type annotation after you fix it.

It’s hard to say what’s going on here because I can’t build the code you posted. It relies on too many other subsystems within your app.

IME problems like this are often caused by a general compile-time problem in your code which is causing the compiler’s type resolution subsystem to head off into the weeds and thus generate an unhelpful error.

My advice is that you reduce the code down to a minimum test case. For example, you could remove the code that creates a User and sets currentUSer and calls saveUser(). As you do this you’ll find that removing some chunk of code causes the code to start working, and you can investigate from there.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

There are two overloads of DispatchQueue.async—one that takes a () -> Void closure, another that takes a DispatchWorkItem. This error would happen because for some reason the compiler doesn't think the closure is of type () -> Void, so it tries to use the DispatchWorkItem overload instead (but that doesn't work either).

I don't know exactly why the compiler isn't getting the closure type right, but you can force it to do so by changing the closure to look like:

DispatchQueue.main.async { () -> Void in
    // contents of closure as before
}

Once you do that, the compiler should either accept the code, or give you a more specific error message that helps you figure out what the problem is. If you do get a more specific error, you'll probably be able to remove the type annotation after you fix it.

Trailing closure bug?
 
 
Q