# Task or actor isolated value cannot be sent

**URL:** <https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879>\
**Category:** Using Swift\
**Tags:** concurrency\
**Created:** [December 27, 2024, 1:34pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879 "2024-12-27T13:34:26Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![vbwo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vbwo/32/38774_2.png) [@vbwo](https://forums.swift.org/u/vbwo)\
**Post date:** [December 27, 2024, 1:34pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/1 "2024-12-27T13:34:26Z")

</div>

Hi everyone,

I'm encountering an error message "Task or actor isolated value cannot be sent" in my EmotionDetectorViewModel class. I'm using Swift concurrency to process video frames from the front camera and detect emotions using a Core ML model.

Here's the relevant part of my code:

```swift
nonisolated func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
  guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

  Task { @MainActor in
    currentBuffer = pixelBuffer
    processCurrentImage()
  }
}

```

The error occurs specifically on the line `currentBuffer = pixelBuffer`. I'm trying to capture the incoming `pixelBuffer` from the camera output and store it in a class property `currentBuffer` for further processing. However, it seems like I can't assign a value captured in a non-isolated context (@MainActor) to a property.

I've searched online and found discussions mentioning that `CVPixelBuffer` is not `Sendable`. Could this be the reason for the error? If so, what's the recommended approach to handle this scenario while adhering to Swift concurrency best practices?

I've been following the guidelines for Swift concurrency but am stuck at this point. Any help would be greatly appreciated!

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [December 27, 2024, 2:42pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/2 "2024-12-27T14:42:01Z")

</div>

Yeah if the type of `pixelBuffer` is not Sendable, I don't think even region-based isolation can help.

This may be something addressable with a `@preconcurrency import`, did you give that a shot?

---

<div class="post-metadata">

**Author:** ![robert.ryan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/robert.ryan/32/38339_2.png) [@robert.ryan](https://forums.swift.org/u/robert.ryan)\
**Post date:** [December 28, 2024, 12:11am UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/3 "2024-12-28T00:11:27Z")

</div>

Does `processCurrentImage` really belong on the main actor? That strikes me as precisely the sort of thing that one wants _off_ the main actor. It is probably only the end result of that process (what the emotion was, the relevant coordinates, etc.) that you want back on the main actor. But not the processing of the image, itself…

---

<div class="post-metadata">

**Author:** ![vbwo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vbwo/32/38774_2.png) [@vbwo](https://forums.swift.org/u/vbwo)\
**Post date:** [December 29, 2024, 2:49pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/4 "2024-12-29T14:49:47Z")

</div>

It works! Thanks!

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [December 29, 2024, 7:47pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/5 "2024-12-29T19:47:15Z")

</div>

Great!

Just keep in mind that an `@preconcurerncy import` is basically a file-wide assertion that you are using the imported framework correctly. I'm not familiar enough with it to know if that's true or not.

---

<div class="post-metadata">

**Author:** ![krzyzanowskim](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/krzyzanowskim/32/1282_2.png) [@krzyzanowskim](https://forums.swift.org/u/krzyzanowskim)\
**Post date:** [December 31, 2024, 10:33pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/6 "2024-12-31T22:33:21Z")

</div>

What are my options if preconcurrency doesn't seem to work?

 ![Screenshot 2024-12-31 at 23.32.04](https://global.discourse-cdn.com/swift/original/3X/4/e/4e6b20ec8b8e767759ac06f5f3d47d5fd0749468.png)

Xcode 16.2

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [January 1, 2025, 12:52pm UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/7 "2025-01-01T12:52:50Z")

</div>

Here's a slightly simplified version of your code that I think is representative and produces the same error:

```swift
@MainActor
class SomeView {
    init() {}
}

class Foo {
    let view: SomeView? = nil
    
    func foo() {
        // error: task or actor isolated value cannot be sent
        Task { @MainActor in
            view
        }
    }
}

```

It's hard to understand what's going on here because the compiler's error message doesn't directly point to the problem. But if we can further simplify and that will make the problem much more clear:

```swift
class Foo {
    func foo() {
        // error: type 'Foo' does not conform to the 'Sendable' protocol
        Task { @MainActor in
            self
        }
    }
}

```

And this explains why the `@preconcurrency import` wasn't helping. The problem has nothing to do with the `STTextView` type. The issue is with `Foo`!

Types that aren't `Sendable` are pretty hard to use with concurrency features, like that `Task` here. It's possible, but can require some pretty complex stuff to make it work.

Given that `Foo` here contains MainActor-only state, one option that often works well is to isolate the whole type.

```swift
@MainActor
class SomeView {
    init() {}
}

@MainActor // <- global actor isolation makes the type Sendable
class Foo {
    let view: SomeView? = nil
    
    func foo() {
        Task { @MainActor in
            view
        }
    }
}

```

(In fact, because now the `foo` method is MainActor as well, the explicit `@MainActor in` for the closure is no longer necessary. But it isn't wrong, so I just left it in to match the original version.)

---

<div class="post-metadata">

**Author:** ![OneSadCookie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/onesadcookie/32/3205_2.png) [@OneSadCookie](https://forums.swift.org/u/OneSadCookie)\
**Post date:** [January 2, 2025, 12:53am UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/8 "2025-01-02T00:53:26Z")

</div>

If that's the only problem, you can stick closer to the original with an explicit capture annotation:

```swift
@MainActor
class SomeView {
    init() {}
}

class Foo {
    let view: SomeView? = nil
    
    func foo() {
        Task { [view] @MainActor in
            view
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![krzyzanowskim](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/krzyzanowskim/32/1282_2.png) [@krzyzanowskim](https://forums.swift.org/u/krzyzanowskim)\
**Post date:** [January 2, 2025, 1:43am UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/9 "2025-01-02T01:43:17Z")

</div>

that is interesting, because it sometimes works. By **sometimes** , I mean that I can see that it doesn't work when "SomeView" is declared in another module

 ![Screenshot 2025-01-02 at 02.40.00](https://global.discourse-cdn.com/swift/original/3X/d/6/d665d191b7923535fb0b8e2780d196af13c722b5.png)

---

<div class="post-metadata">

**Author:** ![dimi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dimi/32/20401_2.png) [@dimi](https://forums.swift.org/u/dimi)\
**Post date:** [January 2, 2025, 2:19am UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/10 "2025-01-02T02:19:29Z")

</div>

> [@krzyzanowskim](#):
>
> that is interesting, because it sometimes works. By **sometimes** , I mean that I can see that it doesn't work when "SomeView" is declared in another module

That’s because types can be automatically marked `Sendable` within the same module if it can be inferred, but you have to manually mark them across module boundaries, since it changes the public interface in a way you may not want to guarantee (kind of like the default `init`’s for structs not being public).

---

<div class="post-metadata">

**Author:** ![mattie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mattie/32/13267_2.png) [@mattie](https://forums.swift.org/u/mattie)\
**Post date:** [January 2, 2025, 11:37am UTC](https://forums.swift.org/t/task-or-actor-isolated-value-cannot-be-sent/76879/11 "2025-01-02T11:37:16Z")

</div>

Yes, it's true that using an explicit capture can work around this problem if the value captured is sendable. That's a useful trick!

But it can also get you into trouble, because it allows you to go further down the this path. The `Foo` type remains difficult to use. I have a hard time imagining how and where you would need to store and reference mutable MainActor state in a type that isn't also itself ultimately created on and used from the MainActor.

I'm not saying using a capture is wrong. Or that this type doesn't represent a reasonable real-world problem. But I do think it is worth caution here, because (today anyways) async methods or Task within a non-Sendable is very hard.

> [@krzyzanowskim](#):
>
> that is interesting, because it sometimes works. By **sometimes** , I mean that I can see that it doesn't work when "SomeView" is declared in another module

What does the definition of `SomeView` look like in that other module?
