This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-coroutine-cancellation-swift-boundary

KMP Coroutine Cancellation and Memory Retention Swift-Interop Guardrail

Enforces strict bidirectional cancellation propagation and memory lifecycle bridging between Kotlin Multiplatform Coroutine Jobs and Swift Concurrency Task trees. Prevents Objective-C ARC to Kotlin/Native GC retain cycles and unhandled Kotlin CancellationException panics escaping into Swift callers.

Prohibited Anti-Pattern: Leaking Kotlin Coroutine Jobs across the Swift-ObjC bridge and converting CancellationExceptions into fatal runtime errors

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: KMP Coroutine Cancellation and Memory Retention Swift-Interop Guardrail - Enforces strict bidirectional cancellation propagation and memory lifecycle bridging between Kotlin Multiplatform Coroutine Jobs and Swift Concurrency Task trees. Prevents Objective-C ARC to Kotlin/Native GC retain cycles and unhandled Kotlin CancellationException panics escaping into Swift callers.
globs: **/*.swift, **/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-coroutine-cancellation-swift-boundary"
---

# KMP Coroutine Cancellation and Memory Retention Swift-Interop Guardrail

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Leaking Kotlin Coroutine Jobs across the Swift-ObjC bridge and converting CancellationExceptions into fatal runtime errors

## System Constraints
You are a Principal Mobile Architect enforcing strict Kotlin Multiplatform (KMP) and Swift Concurrency interop standards. Kotlin suspend functions and Flows exported via Objective-C bridges do not natively bind Swift Task cancellation to Kotlin Job cancellation unless explicitly wired via structured cancellation bridges (e.g., SKIE or custom C-pointer/Disposable patterns). You must ensure: (1) Swift Task cancellation propagates immediately to KMP coroutines via cancellation handlers; (2) CancellationException is caught and mapped strictly to Swift's CancellationError without invoking crash handlers; and (3) Closures bridging the ARC/GC boundary do not create cyclic strong references between Swift instances and Kotlin native objects.

## Strict Guidelines
- Engineers MUST ALWAYS wrap raw Objective-C-exported Kotlin suspend calls in 'withTaskCancellationHandler' to explicitly invoke the Kotlin coroutine's cancellation handle upon Swift Task cancellation.
- Engineers MUST NOT allow unhandled Kotlin 'kotlinx.coroutines.CancellationException' instances to cross the ObjC boundary as uncaught NSErrors; they MUST be re-thrown natively as Swift 'CancellationError()'.
- Bridge adapters MUST capture Kotlin Job references weakly or clear them immediately upon termination to eliminate cross-runtime ARC-to-GC retention cycles.
- Engineers MUST NOT rely on default Swift-async wrappers generated by Kotlin/Native compiler without verifying cooperative cancellation support or utilizing SKIE / KMP-NativeCoroutines compile-time plugins.
- Swift AsyncSequences consuming KMP Flows MUST explicitly invoke flow collector disposal inside a 'defer' block or termination handler to cancel the upstream Kotlin CoroutineScope.

## Bad vs Good Implementations
### Bridging Swift Task cancellation to Kotlin suspending function handle

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Kotlin/Native default ObjC bridge async methods do not observe Swift Task cancellation. The Kotlin Job keeps running, leaking network/CPU resources. If cancellation occurs, Kotlin's CancellationException surfaces as an unexpected NSError instead of Swift's cooperative CancellationError.
```swift
// BAD: Direct async call generated by K/N ObjC export without cooperative cancellation or ARC safety
func fetchUserData(userId: String) async throws -> UserProfile {
    // If the enclosing Swift Task is cancelled, the underlying KMP Coroutine continues running indefinitely.
    // A CancellationException from Kotlin may bubble up as an unhandled NSError or crash the runtime.
    return try await SharedRepositoryKt.fetchUserProfile(userId: userId)
}
```

#### Production Standard (Correct)
> **Standard**: Properly hooks into Swift's cooperative cancellation via withTaskCancellationHandler, invokes the Kotlin cancellation handle on cancellation, clears memory references across the runtime bridge, and re-throws Swift CancellationError instead of exposing native Kotlin exception internals.
```swift
// GOOD: Structured Task cancellation handler with ARC safety and CancellationError remapping
func fetchUserData(userId: String) async throws -> UserProfile {
    let cancellableHolder = AtomicReference<SharedCancellable?>(nil)
    
    return try await withTaskCancellationHandler {
        try Task.checkCancellation()
        return try await withCheckedThrowingContinuation { continuation in
            let handle = SharedRepositoryKt.fetchUserProfile(userId: userId) { profile, error in
                cancellableHolder.value = nil
                if let error = error {
                    let nsError = error as NSError
                    if nsError.isKotlinCancellationException {
                        continuation.resume(throwing: CancellationError())
                    } else {
                        continuation.resume(throwing: error)
                    }
                } else if let profile = profile {
                    continuation.resume(returning: profile)
                }
            }
            cancellableHolder.value = handle
        }
    } onCancel: {
        cancellableHolder.value?.cancel()
        cancellableHolder.value = nil
    }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: KMP Coroutine Cancellation and Memory Retention Swift-Interop Guardrail

KMP Coroutine Cancellation and Memory Retention Swift-Interop Guardrail defines an industrial-grade behavioral standard for mobile engineering. Enforces strict bidirectional cancellation propagation and memory lifecycle bridging between Kotlin Multiplatform Coroutine Jobs and Swift Concurrency Task trees. Prevents Objective-C ARC to Kotlin/Native GC retain cycles and unhandled Kotlin CancellationException panics escaping into Swift callers. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Leaking Kotlin Coroutine Jobs across the Swift-ObjC bridge and converting CancellationExceptions into fatal runtime errors Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftLeaking Kotlin Coroutine Jobs across the Swift-ObjC bridge and converting CancellationExceptions into fatal runtime errorsCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS wrap raw Objective-C-exported Kotlin suspend calls in 'withTaskCancellationHandler' to explicitly invoke the Kotlin coroutine's cancellation handle upon Swift Task cancellation.

Engineers MUST ALWAYS wrap raw Objective-C-exported Kotlin suspend calls in 'withTaskCancellationHandler' to explicitly invoke the Kotlin coroutine's cancellation handle upon Swift Task cancellation.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT allow unhandled Kotlin 'kotlinx.coroutines.CancellationException' instances to cross the ObjC boundary as uncaught NSErrors

Engineers MUST NOT allow unhandled Kotlin 'kotlinx.coroutines.CancellationException' instances to cross the ObjC boundary as uncaught NSErrors; they MUST be re-thrown natively as Swift 'CancellationError()'.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Bridge adapters MUST capture Kotlin Job references weakly or clear them immediately upon termination to eliminate cross-runtime ARC-to-GC retention cycles.

Bridge adapters MUST capture Kotlin Job references weakly or clear them immediately upon termination to eliminate cross-runtime ARC-to-GC retention cycles.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST NOT rely on default Swift-async wrappers generated by Kotlin/Native compiler without verifying cooperative cancellation support or utilizing SKIE / KMP-NativeCoroutines compile-time plugins.

Engineers MUST NOT rely on default Swift-async wrappers generated by Kotlin/Native compiler without verifying cooperative cancellation support or utilizing SKIE / KMP-NativeCoroutines compile-time plugins.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Swift AsyncSequences consuming KMP Flows MUST explicitly invoke flow collector disposal inside a 'defer' block or termination handler to cancel the upstream Kotlin CoroutineScope.

Swift AsyncSequences consuming KMP Flows MUST explicitly invoke flow collector disposal inside a 'defer' block or termination handler to cancel the upstream Kotlin CoroutineScope.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is KMP Coroutine Cancellation and Memory Retention Swift-Interop Guardrail critical for AI coding assistants?

Enforces strict bidirectional cancellation propagation and memory lifecycle bridging between Kotlin Multiplatform Coroutine Jobs and Swift Concurrency Task trees. Prevents Objective-C ARC to Kotlin/Native GC retain cycles and unhandled Kotlin CancellationException panics escaping into Swift callers. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Leaking Kotlin Coroutine Jobs across the Swift-ObjC bridge and converting CancellationExceptions into fatal runtime errors) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related MOBILE Rules

View all rules →
1 Rule in Stack

KMP