Skip to content
Invalid conversion from throwing function

Invalid conversion from throwing function

DodaTech 3 min read

The “Invalid conversion from throwing function” error means you are trying to pass a throwing function (one marked with throws) to a context that expects a non-throwing function. Swift requires explicit handling of all throwing calls.

What It Means

Swift functions can be marked with throws to indicate they may produce an error. When you use a throwing function as a value — assigning it to a variable, passing it as a closure argument, or returning it — the receiving type must also be throwing. The compiler prevents you from silently ignoring the error-handling requirement.

Why It Happens

  • Passing a throwing closure to a non-throwing parameter — a function expects () -> Void but you pass { try risky() }.
  • Assigning a throwing function to a non-throwing variablelet fn: () -> Void = throwingFunction.
  • Returning a throwing function from a non-throwing function — your function return type is () -> Void but you return a throwing closure.
  • Using try inside a non-throwing closure — closures passed to higher-order functions like map, filter, forEach cannot throw unless the closure parameter is marked throws.
  • Combining throwing and non-throwing in a collection — mixing throwing and non-throwing closures in an array or dictionary.

How to Fix It

1. Mark the enclosing function as throws

// ❌ Non-throwing function contains try
func processData() {
    let result = try JSONDecoder().decode(Model.self, from: data)
}

// ✅ Propagate the error
func processData() throws {
    let result = try JSONDecoder().decode(Model.self, from: data)
}

2. Use try? to convert the result to an optional

// ✅ Converts throwing call to optional (nil on error)
if let result = try? JSONDecoder().decode(Model.self, from: data) {
    // use result
}

3. Use try! when you guarantee no error

// ✅ Only when you are certain the call will not fail
let result = try! JSONDecoder().decode(Model.self, from: guaranteedValidData)

4. Handle the error with do-catch

do {
    let result = try JSONDecoder().decode(Model.self, from: data)
} catch {
    print("Decoding failed: \(error)")
}

5. Use rethrows for higher-order functions

If you are writing a function that accepts a throwing closure:

func mapValues<T>(_ transform: (Int) throws -> T) rethrows -> [T] {
    // rethrows means this function only throws if transform throws
}
Can I use try inside a closure passed to map?
Only if the closure parameter type includes throws. The standard map on arrays is non-throwing, so you must use try? or try! inside it or write a custom throwing map.
What is the difference between throws and rethrows?
throws means the function can always throw. rethrows means it only throws if its closure parameter throws. Use rethrows for higher-order functions that wrap throwing closures.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro