When calling a Swift function, method, initializer, or property, Xcode may report an error such as:
Ambiguous use of 'show'
You may also see:
Ambiguous use of 'init'
This error means that the compiler has multiple valid-looking candidates and does not have enough type information to choose exactly one of them.
Common causes include similar overloads, ambiguous numeric literals, nil values without an expected optional type, empty collections, overloaded function references, ambiguous closures, unresolved generic parameters, competing protocol-extension members, same-named declarations from multiple modules, and SwiftUI initializers that cannot be uniquely selected.
The usual fix is to provide more type context so Swift can eliminate every candidate except the one you intend to call.
- What does “Ambiguous use of” mean?
- How is this different from “Invalid redeclaration”?
- Typical situations where this error appears
- Common causes
- 1. Too many similar overloads
- 2. An ambiguous numeric literal
- 3. Passing nil to multiple optional overloads
- 4. Passing an empty array to multiple collection overloads
- 5. An overloaded function reference has no function type
- 6. An overloaded initializer or function is passed directly to map
- 7. A closure parameter type cannot be inferred
- 8. A closure return type is unclear
- 9. A generic parameter remains unresolved
- 10. Optional and non-optional overloads are both available
- 11. Multiple protocol extensions provide the same method
- 12. Protocol requirements and extension methods compete
- 13. Same-named declarations come from multiple modules
- 14. SwiftUI exposes many initializer overloads
- 15. A Binding is confused with its wrapped value
- 16. Picker selection and tag types do not line up
- 17. Multiple generic initializers are available
- 18. Literal-convertible custom types increase the candidate set
- 19. Default arguments make overloads overlap
- 20. Another compiler error is the real cause
- What to check first
- Solution 1: Add an explicit variable type
- Solution 2: Explicitly convert or cast the argument
- Solution 3: Give nil a concrete optional type
- Solution 4: Give an empty collection an element type
- Solution 5: Give an overloaded function reference a function type
- Solution 6: Replace an ambiguous function reference with a closure
- Solution 7: Specify the closure parameter type
- Solution 8: Specify the closure return type
- Solution 9: Specify the map result type
- Solution 10: Specify the compactMap output type
- Solution 11: Make a generic container concrete
- Solution 12: Add result context to generic functions
- Solution 13: Reduce the number of similar overloads
- Solution 14: Avoid overlapping overloads created by default arguments
- Solution 15: Simplify optional overloads
- Solution 16: Resolve competing protocol-extension methods
- Solution 17: Qualify same-named types by module
- Solution 18: Wrap confusing external APIs
- Solution 19: Make initializer arguments explicit
- Solution 20: Pass SwiftUI bindings correctly
- Solution 21: Check custom SwiftUI bindings
- Solution 22: Keep Picker selection and tag types consistent
- Solution 23: Unwrap SwiftUI optionals before passing them on
- Solution 24: Split large SwiftUI expressions
- Solution 25: Break complex expressions into typed intermediate values
- Solution 26: Specify numeric types explicitly
- Solution 27: Convert Int, Double, CGFloat, and similar types deliberately
- Solution 28: Use clearer function names instead of excessive overloading
- Solution 29: Reduce nested conversions at the call site
- Solution 30: Redesign your own ambiguous APIs
- If Xcode says “Ambiguous use of init”
- If Xcode says “Ambiguous use of subscript”
- If Xcode reports an ambiguous operator
- If the error occurs in SwiftUI
- If the error occurs in map or compactMap
- If the error occurs with protocol extensions
- If same-named types come from multiple modules
- Will Clean Build Folder fix it?
- Should you delete DerivedData?
- What you should avoid
- Fast troubleshooting checklist
- Summary
What does “Ambiguous use of” mean?
Swift supports function overloading.
For example:
func show(_ value: Int) { print("Int: \(value)") }
func show(_ value: Double) {
print("Double: (value)")
}
In straightforward calls, Swift can often infer the intended overload from the argument type.
In more complicated expressions involving generics, literals, closures, or optionals, multiple candidates may remain equally valid.
Swift then reports:
Ambiguous use of 'show'
How is this different from “Invalid redeclaration”?
An error such as:
Invalid redeclaration of 'show'
means the declarations themselves conflict because Swift cannot treat them as distinct definitions.
By contrast:
Ambiguous use of 'show'
usually means the declarations are individually valid, but the call site does not provide enough information to choose one.
Key point: Invalid redeclaration is primarily a declaration problem. Ambiguous use is primarily an overload-resolution or type-inference problem at the use site.
Typical situations where this error appears
- Several function overloads have similar signatures
- Multiple initializer candidates remain valid
- A numeric literal has no clear concrete type
- nil does not reveal its wrapped optional type
- An empty array or dictionary has no element type
- A closure parameter cannot be inferred
- A closure return type cannot be inferred
- An overloaded function reference is passed to map or another higher-order function
- A generic parameter remains unresolved
- Several protocol extensions provide the same member name
- Multiple imported modules contain the same type or function name
- SwiftUI has several compatible-looking generic initializers
- A Binding is confused with a plain value
- Optional and non-optional overloads compete
Common causes
1. Too many similar overloads
func process(_ value: Int) { }
func process(_ value: Double) {
}
If the argument’s concrete numeric type is not known, both candidates may remain possible.
2. An ambiguous numeric literal
Swift numeric literals receive their concrete type from context.
When that context is missing or multiple numeric overloads fit, overload resolution can become ambiguous.
3. Passing nil to multiple optional overloads
func setValue(_ value: String?) { }
func setValue(_ value: Int?) {
}
setValue(nil)
nil alone does not tell Swift whether you mean String? or Int?.
4. Passing an empty array to multiple collection overloads
func process(_ values: [String]) { }
func process(_ values: [Int]) {
}
process([])
The empty array has no element-type information.
5. An overloaded function reference has no function type
func convert(_ value: Int) -> String { String(value) }
func convert(_ value: Double) -> String {
String(value)
}
let handler = convert
Swift cannot determine which convert function should be stored.
6. An overloaded initializer or function is passed directly to map
let values = numbers.map(String.init)
If the input or output type is insufficiently constrained, one of several String initializers may appear valid.
7. A closure parameter type cannot be inferred
someMethod { value in print(value) }
Generic or overloaded APIs may leave the type of value unresolved.
8. A closure return type is unclear
Different branches may produce incompatible results, or all branches may return nil without identifying an output type.
9. A generic parameter remains unresolved
func make<T>() -> T { fatalError() }
let value = make()
This may produce a generic inference error directly, but in an overloaded expression it can also contribute to an ambiguous-use diagnostic.
10. Optional and non-optional overloads are both available
func show(_ value: String) { }
func show(_ value: String?) {
}
Optional promotion and surrounding context can make overload selection harder to reason about.
11. Multiple protocol extensions provide the same method
A concrete type conforming to several protocols may inherit competing default implementations with the same member name.
12. Protocol requirements and extension methods compete
Complex protocol hierarchies and conditional extensions can create several available members with similar signatures.
13. Same-named declarations come from multiple modules
Two imported frameworks may both define User, Configuration, or another common name.
14. SwiftUI exposes many initializer overloads
Views such as TextField, Button, Picker, and navigation APIs often have several generic initializers.
A missing Binding or type mismatch can leave more than one candidate in play or eliminate the one you intended.
15. A Binding is confused with its wrapped value
With:
@State private var name = ""
name is String, while $name is Binding<String>.
16. Picker selection and tag types do not line up
The Picker’s generic selection type must be consistent with its tag values.
17. Multiple generic initializers are available
Conditional initializers and protocol-constrained initializers can overlap for the same concrete type.
18. Literal-convertible custom types increase the candidate set
Types conforming to protocols such as ExpressibleByIntegerLiteral or ExpressibleByStringLiteral can compete with standard-library types in an underconstrained expression.
19. Default arguments make overloads overlap
Two overloads may become callable with the same argument list because their remaining parameters have defaults.
20. Another compiler error is the real cause
Especially in SwiftUI or complex generic expressions, an inner type error may prevent normal overload resolution and surface as an ambiguous-use error elsewhere.
What to check first
1. Identify the declaration named in the diagnostic
For example:
Ambiguous use of 'init'
means the compiler cannot choose among multiple initializers.
2. Inspect available overloads with Xcode autocomplete
Retype the function or initializer name and compare the candidate signatures Xcode offers.
3. Use Quick Help or Jump to Definition
Compare parameter labels, parameter types, generic constraints, and return types.
4. Check the earliest compiler diagnostic
The ambiguous-use message may be secondary.
Important: In SwiftUI especially, fix earlier Binding, optional, argument-label, and generic errors before treating the ambiguous-use message as the root cause.
Solution 1: Add an explicit variable type
let value: Int = 10
Now overload resolution has a concrete numeric type.
Solution 2: Explicitly convert or cast the argument
show(10 as Int)
or:
show(10.0 as Double)
Note: Use an explicit type only when it represents your actual intent. Do not add arbitrary casts merely to silence the compiler.
Solution 3: Give nil a concrete optional type
setValue( nil as String? )
or:
let value: String? = nil setValue(value)
Solution 4: Give an empty collection an element type
process( [] as [String] )
or:
let values: [String] = [] process(values)
Solution 5: Give an overloaded function reference a function type
func convert(_ value: Int) -> String { String(value) }
func convert(_ value: Double) -> String {
String(value)
}
let handler: (Int) -> String = convert
This selects the Int overload.
Solution 6: Replace an ambiguous function reference with a closure
let strings = numbers.map { value in String(value) }
The closure often gives Swift clearer input-type context than an overloaded function reference.
Solution 7: Specify the closure parameter type
let result = values.map { (value: Int) in
String(value)
}
Solution 8: Specify the closure return type
let result = values.map { (value: Int) -> String in
String(value)
}
Solution 9: Specify the map result type
let strings: [String] = numbers.map { value in String(value) }
Solution 10: Specify the compactMap output type
let numbers: [Int] = strings.compactMap { (text: String) -> Int? in
Int(text)
}
Solution 11: Make a generic container concrete
let box: Box<String> = Box(value: nil)
Solution 12: Add result context to generic functions
func makeValue<T>() -> T { fatalError() }
let value: User = makeValue()
Swift can now infer T as User.
Solution 13: Reduce the number of similar overloads
If an API is difficult to call correctly, consider clearer names:
func loadUserByID(_ id: Int) { }
func loadUserByName(_ name: String) {
}
This removes overload-resolution work from the call site entirely.
Solution 14: Avoid overlapping overloads created by default arguments
Problematic API design:
func show( value: Int, animated: Bool = true ) { }
func show(
value: Int,
highlighted: Bool = false
) {
}
Both can be called as:
show(value: 10)
Rename or redesign one overload so the call is unique.
Solution 15: Simplify optional overloads
func show(_ value: String) { }
func show(_ value: String?) {
}
Check whether both are really necessary. One optional-aware implementation may be easier to use and maintain.
Solution 16: Resolve competing protocol-extension methods
protocol A { }
protocol B {
}
extension A {
func run() {
print("A")
}
}
extension B {
func run() {
print("B")
}
}
struct Worker: A, B {
func run() {
print("Worker")
}
}
An explicit implementation on the concrete type removes the ambiguity.
Solution 17: Qualify same-named types by module
FrameworkA.User
versus:
FrameworkB.User
Solution 18: Wrap confusing external APIs
If several imported functions share similar names, create an application-level wrapper with a clearer purpose:
func loadLocalUser( id: Int ) { LocalSDK.load(id: id) }
Solution 19: Make initializer arguments explicit
let value = SomeType( text: "Hello", count: 10 )
If literals remain ambiguous, add concrete argument types as well.
Solution 20: Pass SwiftUI bindings correctly
@State private var name = ""
TextField(
"Name",
text: $name
)
The initializer expecting Binding<String> needs $name, not the wrapped String value.
Solution 21: Check custom SwiftUI bindings
struct EditView: View { @Binding var text: String
var body: some View {
TextField(
"Text",
text: $text
)
}
}
struct ContentView: View {
@State private var text = ""
var body: some View {
EditView(
text: $text
)
}
}
Solution 22: Keep Picker selection and tag types consistent
@State private var selected = 0
Picker(
"Option",
selection: $selected
) {
Text("One").tag(0)
Text("Two").tag(1)
}
If selection is Int, use Int tags as well.
Solution 23: Unwrap SwiftUI optionals before passing them on
if let selectedUser { UserView( user: selectedUser ) }
Solution 24: Split large SwiftUI expressions
var body: some View { VStack { headerView contentView } }
private var contentView: some View {
UserListView(
users: users
)
}
Smaller view-builder expressions make the real type mismatch easier to locate.
Solution 25: Break complex expressions into typed intermediate values
Instead of:
let result = users .map { $0.age } .map(String.init)
use:
let ages: [Int] = users.map { user in user.age }
let result: [String] =
ages.map { age in
String(age)
}
Solution 26: Specify numeric types explicitly
let width: Double = 10 let count: Int = 10
This is particularly useful when APIs have overloads for several numeric types.
Solution 27: Convert Int, Double, CGFloat, and similar types deliberately
let count = 10
let width: CGFloat =
CGFloat(count)
Solution 28: Use clearer function names instead of excessive overloading
func formatDate( _ value: Date ) -> String { ... }
func formatNumber(
_ value: Double
) -> String {
...
}
Clearer names can eliminate entire classes of overload ambiguity.
Solution 29: Reduce nested conversions at the call site
Move complex optional transformations and casts into intermediate values or helper methods so every step has a clear type.
Solution 30: Redesign your own ambiguous APIs
If your own APIs frequently trigger ambiguous-use errors, inspect the declarations themselves.
Common design problems include:
- Overloads differing only in subtle labels
- Default arguments that make several overloads callable the same way
- Many optional and non-optional overload pairs
- Overly complex generic constraints
Simplifying the API can be better than repeatedly adding type annotations at every call site.
If Xcode says “Ambiguous use of init”
Several initializers remain possible.
For example:
init(value: String?) init(value: Int?)
makes this ambiguous:
SomeType( value: nil )
Specify the intended optional type:
SomeType( value: nil as String? )
If Xcode says “Ambiguous use of subscript”
A collection or custom type may expose multiple subscript candidates.
Check the index or key type and the expected result type.
let dictionary: [String: Int] = [ "one": 1 ]
let value: Int? =
dictionary["one"]
If Xcode reports an ambiguous operator
Operators are overloaded too.
When numeric types differ, normalize them explicitly:
let intValue: Int = 10 let doubleValue: Double = 20
let result =
Double(intValue) + doubleValue
If the error occurs in SwiftUI
Use this troubleshooting order:
- Check for an earlier compiler error.
- Inspect the available initializer overloads.
- Verify argument labels.
- Verify argument types.
- Check Binding versus plain values.
- Check optional values.
- Check Picker selection and tag types.
- Check closure parameter types.
- Split a large body into smaller views.
If the error occurs in map or compactMap
Replace overloaded function references with explicit closures:
let strings: [String] = numbers.map { value in String(value) }
For compactMap:
let numbers: [Int] = strings.compactMap { text in Int(text) }
If the error occurs with protocol extensions
When several protocol extensions provide the same member, add an implementation to the concrete conforming type to define exactly which behavior should be used.
If same-named types come from multiple modules
Qualify the type explicitly:
FrameworkA.Configuration
or:
FrameworkB.Configuration
Will Clean Build Folder fix it?
Usually not.
This error is normally caused by overload resolution or insufficient type information in source code.
You can use:
Product → Clean Build Folder
as a secondary troubleshooting step, but it cannot resolve a genuinely ambiguous expression.
Should you delete DerivedData?
If Xcode indexing appears stale, you can try:
rm -rf ~/Library/Developer/Xcode/DerivedData/*
but deleting build artifacts does not choose between two overloads that are both valid according to your source code.
Note: Check overload candidates and type context before treating this as an Xcode cache problem.
What you should avoid
Do not add large numbers of forced casts or replace everything with Any just to silence an ambiguous-use error.
The compiler needs a clear statement of which type and overload your code intends to use.
Forced casts can reduce type safety and may introduce runtime crashes.
Prefer explicit variable types, argument types, closure types, and well-designed APIs.
Fast troubleshooting checklist
- Identify the function, method, initializer, or property named in the error.
- Inspect available overloads in Xcode autocomplete.
- Compare argument labels.
- Compare argument types.
- Add an explicit result type.
- Give numeric literals a concrete type.
- Give nil a concrete optional type.
- Give empty collections an element type.
- Give overloaded function references a function type.
- Specify closure parameter types.
- Specify closure return types.
- Specify generic types where necessary.
- Check competing protocol-extension methods.
- Check same-named declarations from multiple modules.
- In SwiftUI, check bindings, optionals, and initializer candidates.
Summary
Swift’s “Ambiguous use of” error means that the compiler has more than one possible function, method, initializer, property, subscript, or operator and cannot determine which candidate your code intends to use.
Common causes include similar overloads, numeric literals, nil values, empty collections, overloaded function references, closures, generic types, protocol extensions, same-named declarations from different modules, and SwiftUI initializer selection.
The most common solution is to provide more concrete type information. Add a variable type, argument type, result type, closure signature, optional type, or generic specialization so Swift can reduce the candidate set to one.
In SwiftUI, also check Binding versus plain values, optional data, Picker selection types, and any earlier compiler errors inside the view builder.
If ambiguous-use errors happen frequently in your own APIs, consider simplifying your overloads, removing overlapping default arguments, and using clearer function names rather than relying on increasingly complex type inference.
