Has anyone else suddenly encountered an explosion of “Main actor-isolated property ‘foo’ can not be referenced from a nonisolated context” errors when updating to Xcode 26 Beta 6? A project that has zero errors when compiled with Xcode 26 Beta 5 is suddenly flooded with 30+ in Beta 6.
Here’s a simplified example:
protocol Namable {
var name: String { get }
}
@Generable
struct Foo: Hashable {
let nameValue: String
}
extension Foo.PartiallyGenerated: nonisolated Namable {
var name: String {
// Remember: PartiallyGenerated makes all values Optionals
return nameValue ?? "No Name Set"
}
}
extension Foo.PartiallyGenerated: nonisolated Codable {
enum CodingKeys: String, CodingKey {
case nameValue = "name"
}
func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .nameValue) // ERROR: Main actor-isolated property 'name' can not be referenced from a nonisolated context
}
}
Changing the conformance to Namable so that each property is marked nonisolated solves the problem:
extension Foo.PartiallyGenerated: nonisolated Namable {
nonisolated var name: String {
// Remember: PartiallyGenerated makes all values Optionals
return nameValue ?? "No Name Set"
}
}
Why? I told the compiler the entire conformance to Namable is nonisolated. Why do I need to decorate each conforming computed property with nonisolated? Especially on a type that’s already nonisolated!? (Foo.PartiallyGenerated).
I suddenly have to throw 800 nonisolated keywords into this codebase to get it to compile with Xcode 26 beta 6 while none of this was an issue in beta 5.
Why is name suddenly main actor-isolated? The type adopting the protocol isn’t. The conformance to that protocol isn’t. It’s like the new “everything is main actor-isolated until you tell me it isn’t” mode has gone a little nuts.
It sounds like your project suddenly had its default isolation set to MainActor, so you'll want to check that build setting in the "Swift Concurrency" section. In my small project I haven't seen any changes.
I’ve seen the opposite over time in my projects where approachable concurrency is enabled and default actor isolation is set to MainActor. i.e. a vast reduction in having to use nonisolated and @MainActor.
The new main-actor-by-default mode is quite nice. But it seems to have gotten more thorough/severe in the lastest toolchain.
In the example above, both the underlying type and the conformance to the protocol are marked nonisolated, but the compiler still forces the protocol method to the main actor. I don’t see why that’s desirable or expected.
If I mark a class as nonisolated, I don’t have to decorate each property as well. So why should we have to decorate each protocol method implementation if we’ve marked the protocol conformance as nonisolated?
In my case, I have a protocol that both Foo.PartiallyGenerated and FooModel (a SwiftData model class) adopt so that a single SwiftUI view can be used to display either one. The protocol has many methods, so it’s a lot of extra nonisolateds.
The compiler will allow that, yes, but if you do so you’ll see random errors in SwiftUI Views that “nonisolated can be applied only to inheritance declarations” (wording approximate because I’m away from Xcode).
I say “random” because the errors show up in the Xcode sidebar and will prevent the app from building, but if you click the error to go to it, there is no error shown in the actual View and the error in the sidebar suddenly disappears until you try to build again.
Essentially, SwiftUI can’t work with decorated extensions.