WebAssembly and @MainActor – nothing runs

Hello! I’m trying to update to Swift 6.2 and the official Wasm SDK and I’m having a hard time with @MainActor. It seems that anything annotated with @MainActor is simply never called.

I am on the current main branch of JavaScriptKit (version 0.27.0 was also the same) and have a simple main.swift that looks like this:

import JavaScriptEventLoop
JavaScriptEventLoop.installGlobalExecutor() // not sure if this is necessary any more

print("this gets printed")

Task { @MainActor in
   print("this does not get printed")
}

I don’t care about the actual threading here at all – everything runs in the same main thread anyway. But it’s important for us to keep the @MainActor annotations in practice because we’re sharing code with iOS, Android, etc.

Could anybody who has run into the same issue provide any thoughts or suggestions here?

1 Like

In reality, my main function just exposes a callback to JS that is called later. That part of the machinery works – main exits, and then the callback I’ve set can be called without issue. In my “real” code, the @MainActor Task is then called within that callback, and it does nothing. But it’s equally reproducible without the intermediate step.

In that sense, I have never experienced the issue you’re describing before. Are you referring specifically to Wasm or to Swift in general?

From experience the above pattern has worked fine before in Swift Wasm, but it’s something to consider. Maybe I need to loop the main run loop, but it’d be news to me in Wasm and I didn’t see anything like that in the current examples eg. in the JavaScriptKit repo.

There's a regression in concurrency APIs used in JavaScript event loop integration in Swift 6.2.0. I'd advise using main snapshots in the meantime if you need JavaScriptEventLoop integration to work.

We also have a PR for release/6.2 branch open that potentially in some future 6.2.x release would unblock custom executors and fix the issue that you're seeing [Concurrency] Updates after second SE pitch. by al45tair · Pull Request #83950 · swiftlang/swift · GitHub

Hi @Max_Desiatov, thank you for clarifying! That helps a lot. I’m not sure I need JavaScriptEventLoop, but it sounds like you’re suggesting that this would get the MainExecutor draining.

I did see the work with Executors, I was just hoping to use the 6.2 release for all our platforms. I will think about how to proceed here, but I think that’s enough info for me to work with. Thank you again!

1 Like

Hey @Max_Desiatov, it seems we have to update to Swift 6.2+ because the OSS 6.1 toolchain doesn’t work with swift build in Tahoe 26.x because Darwin, which is used internally by SwiftPM and is not included in the OSS toolchain, was compiled with Swift 6.2.

That leaves us in a tricky spot. We must use 6.2 but it’s unusable with Wasm. You mentioned an open PR that opens up the new Executor APIs – do you know if there is any snapshot or release we could use to get things building and running on macOS 26.x for now? Separate to the Executor work, is there a patch for the 6.2 regression?

Any snapshot off main should work, and if it doesn't please let me know.

That custom executors PR on release/6.2 branch is the intended patch for the 6.2 regression.

1 Like

Hi @Max_Desiatov, the Wasm SDK and toolchain builds seem to be misaligned, so I think I’m stuck again.

swiftly use main-snapshotmain-snapshot-2025-10-16

Then, with a command also directly from swift.org (noting that the snapshot is even dated identically):

swift sdk install https://download.swift.org/development/wasm-sdk/swift-DEVELOPMENT-SNAPSHOT-2025-10-16-a/swift-DEVELOPMENT-SNAPSHOT-2025-10-16-a_wasm.artifactbundle.tar.gz --checksum aa7251d0fbc44c0894335363f19e37a39dc323d3d8274ee8a7fe03b537c6cf67

So far so good, but then:

swift build --swift-sdk swift-DEVELOPMENT-SNAPSHOT-2025-10-16-a_wasm

...
ERROR
module compiled with Swift 6.3 cannot be imported by the Swift 6.2 compiler: ~/Library/org.swift.swiftpm/swift-sdks/swift-DEVELOPMENT-SNAPSHOT-2025-10-16-a_wasm.artifactbundle/swift-DEVELOPMENT-SNAPSHOT-2025-10-16-a_wasm/wasm32-unknown-wasip1/swift.xctoolchain/usr/lib/swift_static/wasi/Swift.swiftmodule/wasm32-unknown-wasip1.swiftmodule

I don’t see any possibility of getting a “more” up-to-date main branch toolchain than this, so I’m not sure what options I reasonably have here :confused:

Would you mind double checking if you are using an aligned version of the compiler? You can check the commit revision from swiftc -version and also swiftc -print-target-info with recent snapshots prints tag version.

swiftc -version
Apple Swift version 6.2-dev (LLVM 8e19caa07d62341, Swift bf2671510d1631a)
Target: arm64-apple-macosx26.0
Build config: +assertions
swiftc -print-target-info

{
  "compilerVersion": "Apple Swift version 6.2-dev (LLVM 8e19caa07d62341, Swift bf2671510d1631a)",
  "swiftCompilerTag": "swift-6.2-DEVELOPMENT-SNAPSHOT-2025-10-09-a",
  "target": {
    "triple": "arm64-apple-macosx26.0",
    "unversionedTriple": "arm64-apple-macosx",
    "moduleTriple": "arm64-apple-macos",
    "platform": "macosx",
    "arch": "arm64",
    "pointerWidthInBits": 64,
    "pointerWidthInBytes": 8,
    "swiftRuntimeCompatibilityVersion": "6.2",
    "compatibilityLibraries": [ ],
    "openbsdBTCFIEnabled": false,
    "librariesRequireRPath": false
  },
  "paths": {
    "runtimeLibraryPaths": [
      "~/Library/Developer/Toolchains/swift-6.2-DEVELOPMENT-SNAPSHOT-2025-10-09-a.xctoolchain/usr/lib/swift/macosx",
      "/usr/lib/swift"
    ],
    "runtimeLibraryImportPaths": [
      "~/Library/Developer/Toolchains/swift-6.2-DEVELOPMENT-SNAPSHOT-2025-10-09-a.xctoolchain/usr/lib/swift/macosx"
    ],
    "runtimeResourcePath": "~/Library/Developer/Toolchains/swift-6.2-DEVELOPMENT-SNAPSHOT-2025-10-09-a.xctoolchain/usr/lib/swift"
  }
}

It looks like you are using a snapshot toolchain from 6.2 release branch with a snapshot SDK from the main branch

It really does look like that. I will try again!

Sorry @kateinoigakukun @Max_Desiatov, Yuta was right.

I had installed the main snapshot and even run swiftly use main-snapshot but: due to a quirk in our repo structure, it had not overwritten the Swift compiler version in the subdirectory where Package.swift lives, so the change was not registered. User error!

It’s building now, and @MainActor runs as it did before. That’s excellent! Thank you both!

Unfortunately there is now an issue where distributed actors pause in the same way that @MainActor did before. Is this expected? Do I need to update WebWorkerKit with some new Executor APIs somehow?

1 Like

I am happy to report that there is also no issue with Distributed or WebWorkerKit. What I was experiencing was “just” a stack overflow.

We had experienced this in the past, but had removed -Xlinker -z -Xlinker stack-size=131072 from our build invocation again because it appeared unnecessary in the last few Swift versions. I added it back and the freezes I saw go away.

Thank you @Max_Desiatov and @kateinoigakukun for your help. With this current state we can release an update :rocket:

1 Like

IIUC stack usage might be improved for async code when this issue is resolved: Support `swifttailcc` on WebAssembly · Issue #69333 · swiftlang/swift · GitHub

1 Like