Upload debug symbols for Kotlin Multiplatform

Kotlin Multiplatform apps produce different debug symbols for each target. Configure uploads for every target where you ship minified or native code.

  1. Download the PostHog CLI

    Required

    Install posthog-cli:

    npm install -g @posthog/cli

  2. Authenticate the PostHog CLI

    Required

    To authenticate the CLI, call the login command. This opens your browser where you select your organization, project, and API scopes to grant:

    Terminal
    posthog-cli login

    If you are using the CLI in a CI/CD environment such as GitHub Actions, you can set environment variables to authenticate:

    Environment VariableDescriptionSource
    POSTHOG_CLI_HOSTThe PostHog host to connect to [default: https://us.posthog.com]Project settings
    POSTHOG_CLI_PROJECT_IDPostHog project IDProject settings
    POSTHOG_CLI_API_KEYPersonal API key with error tracking write and organization read scopesAPI key settings

    You can also use the --host option instead of the POSTHOG_CLI_HOST environment variable to target a different PostHog instance or region. For EU users:

    Terminal
    posthog-cli --host https://eu.posthog.com [CMD]

  3. Upload Android mappings

    If your Android release uses ProGuard or R8, apply the PostHog Android Gradle plugin to the Android application module. The plugin injects a mapping ID into the app and uploads the matching mapping file during the Gradle build.

    androidApp/build.gradle.kts
    plugins {
    id("com.android.application")
    id("com.posthog.android") version "<version>"
    }

    Follow the Android mappings guide for authentication options and the complete Gradle configuration.

  4. Upload iOS dSYMs

    The iOS app's dSYM files let PostHog resolve Kotlin and Swift frames. In the Xcode app target:

    1. Open Build Settings and set Debug Information Format to DWARF with dSYM File for Release builds.
    2. Set User Script Sandboxing (ENABLE_USER_SCRIPT_SANDBOXING) to No.
    3. Add a Run Script build phase after the build phases that generate the app and dSYMs.
    4. Add this script:
    Terminal
    if [[ "${CONFIGURATION:-}" != "Release" ]]; then
    exit 0
    fi
    export PATH="/opt/homebrew/bin:/usr/local/bin:${HOME}/.posthog:${PATH}"
    POSTHOG_CLI_PATH="${POSTHOG_CLI_PATH:-$(command -v posthog-cli)}"
    if [[ -z "${POSTHOG_CLI_PATH}" ]]; then
    echo "posthog-cli was not found"
    exit 1
    fi
    "${POSTHOG_CLI_PATH}" dsym upload \
    --directory "${DWARF_DSYM_FOLDER_PATH}" \
    --main-dsym "${DWARF_DSYM_FILE_NAME}" \
    --release-name "${PRODUCT_BUNDLE_IDENTIFIER}" \
    --release-version "${MARKETING_VERSION}" \
    --build "${CURRENT_PROJECT_VERSION}"
    1. Add this path to the build phase's Input Files:
    text
    $(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(EXECUTABLE_NAME)

    If your production configuration has another name, update the CONFIGURATION check. Add --include-source to the upload command if you want source code context in stack traces. See the iOS dSYM guide for troubleshooting and test-crash instructions.

  5. Upload web source maps

    For Kotlin/JS, run your production browser distribution task and locate the generated JavaScript bundle and source map. Inject PostHog metadata, upload the source map, and deploy the injected assets:

    Terminal
    DIST_DIR="<path-to-production-assets>"
    RELEASE_NAME="<application-id>"
    RELEASE_VERSION="<release-version>"
    posthog-cli sourcemap inject \
    --directory "${DIST_DIR}" \
    --release-name "${RELEASE_NAME}" \
    --release-version "${RELEASE_VERSION}"
    posthog-cli sourcemap upload \
    --directory "${DIST_DIR}" \
    --release-name "${RELEASE_NAME}" \
    --release-version "${RELEASE_VERSION}"

    The deployed JavaScript files must be the files modified by sourcemap inject. If your web target uses another output format, follow the web source map guide for the generated assets.

  6. Verify debug symbols upload

    Checkpoint
    Confirm that debug symbols are successfully uploaded to PostHog.Check symbol sets in PostHog
JVM desktop builds

Compose Desktop's default release configuration keeps readable class names, source file names, and line numbers, so it does not need a mapping upload. The PostHog Kotlin Multiplatform SDK cannot restore readable stack traces for JVM desktop builds that use custom obfuscation because those builds do not include the map ID required to match an exception with its mapping file.

Was this page useful?