Skip to content
Latchkey

Kotlin Multiplatform "target ... not registered" / missing target in CI

A Kotlin Multiplatform build declares targets (jvm, js, native, android) in the kotlin {} block. A CI failure occurs when a task references a target that is not declared for that runner OS, or when a Kotlin/Native target is built on an OS that cannot host it.

What this error means

The build fails with a message that a target is not registered, an unknown task like linkDebugExecutableLinuxX64 is requested, or Kotlin/Native cannot build a target on the current host OS.

Gradle
> Task 'iosArm64Test' not found in project ':shared'.
> Cannot build Kotlin/Native target 'iosArm64' on host os 'linux'.

Common causes

A target is built on the wrong host OS

Apple targets (iOS, macOS) can only be built on a macOS runner. Requesting them on a Linux runner fails because the target cannot be hosted there.

The target is not declared for this build

A CI task names a target the kotlin {} block never registered, so Gradle cannot find the task.

How to fix it

Match the runner OS to the target

Run Apple targets on macOS runners and build only host-compatible targets on Linux.

.github/workflows/ci.yml
# build only JVM/JS on Linux; run Apple targets on macOS
runs-on: macos-14
# or, on Linux:
# ./gradlew :shared:jvmTest :shared:jsTest

Declare the targets the build needs

  1. List declared targets in the kotlin {} block.
  2. Add or gate the target so the requested task exists on that OS.
  3. Run only the tasks valid for the runner.
build.gradle.kts
kotlin {
    jvm()
    js(IR) { nodejs() }
    iosArm64() // build this target on macOS runners only
}

How to prevent it

  • Split KMP CI jobs by OS: Apple targets on macOS, JVM/JS/Linux native elsewhere.
  • Only invoke tasks for targets valid on the current runner.
  • Keep declared targets and CI matrix in sync.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →