Skip to content

Android fails to build #4444

Closed as duplicate
Closed as duplicate

Description

@m-bert

Caution

This issue was created to test Code Rabbit possibilities

Description

My android app fails randomly

Steps to reproduce

1
2.
3

Repro

export default function App() {
  return <View />;
}

A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug.

https://github.com/software-mansion/react-native-gesture-handler

Gesture Handler version

3.2.1

React Native version

0.87.0

Platforms

Android, iOS

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

Activity

  1. github-actions commented on Aug 19, 2026

    @github-actions

    Hey! 👋

    The issue doesn't seem to contain a minimal reproduction.

    Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

  2. coderabbitai commented on Aug 19, 2026

    @coderabbitai

    Coding Plan

    Summary

    • Harden the configuration-time detection functions in android/build.gradle so variant, dependency, and CMake-flag selection is deterministic and configuration-cache safe.
    • Replace silent fallback with explicit, named errors when autolinking detection is ambiguous.
    • Strengthen packagingOptions to resolve duplicate native .so libraries instead of failing the merge step.
    • Add configuration-time diagnostics so any remaining intermittent failure includes the resolved decisions and versions.

    Impacted files and follow-up guidance

    • packages/react-native-gesture-handler/android/build.gradle: primary file for all phases. Update getExternalLibVersion, shouldUseCommonInterfaceFromReanimated, shouldUseCommonInterfaceFromRNSVG, shouldUseRuntimeFromWorklets, the packagingOptions block, and add the diagnostics logging.
    • packages/react-native-gesture-handler/android/src/main/jni/CMakeLists.txt: no change required. It uses the now-stable REACT_NATIVE_DIR and RNGH_USE_WORKLETS values.
    • Follow-up agent instructions: verify the build with the configuration cache enabled and disabled. Run a clean build and an incremental build after changing the installed reanimated/worklets version to confirm the variant re-evaluates. Confirm merge*NativeLibs passes with the reanimated and svg dependencies both present and both absent.
    Design Choices
    Design Choice 1: Which failure mode does the "random" Android build failure correspond to?

    Options Considered:

    1. Wait for logs and make no code change.
    2. Harden the two documented non-deterministic causes: flaky variant/version detection and duplicate native .so packaging.
    3. Rewrite the entire variant-selection mechanism.

    Chosen Option: 2

    Rationale: The ticket has no logs, so the exact error is unknown. Exploration and web search point to two documented, non-deterministic failure modes. Option 2 fixes the concrete, documented fragility points without over-engineering. It aligns with the existing detection and packagingOptions patterns.

    💡 User Tips

    Regenerate the plan with different choices with @coderabbitai <feedback>.

    Implementation Steps

    Phase 1: Make build-variant and native-flag detection deterministic

    This phase removes the non-deterministic and stale-decision behavior in the detection functions. It ensures that the same installed dependency set always produces the same source set, the same linked dependencies, and the same CMake flags, even when the Gradle configuration cache is enabled.

    Task 1: Track dependency package.json reads as Gradle inputs

    Make the version detection participate in Gradle's configuration-cache input tracking so a dependency change always causes a re-evaluation of the variant decision.

    • Update getExternalLibVersion in packages/react-native-gesture-handler/android/build.gradle to read the dependency package.json through Gradle providers (for example providers.fileContents(...) on a RegularFile) instead of new File(...).text.
    • Confirm the resolved variant decision comes from these provider values, so it is re-computed when the file content changes.
    • Keep the existing major/minor/patch comparison logic unchanged.
    Task 2: Fail loudly on ambiguous or missing detection

    Replace silent fallback to the "no-op" variant with explicit, actionable errors when a package is installed but not resolvable as a named subproject.

    • In shouldUseCommonInterfaceFromReanimated, shouldUseCommonInterfaceFromRNSVG, and shouldUseRuntimeFromWorklets, keep the return value false only when the package is genuinely absent.
    • When rootProject.subprojects.find { ... } returns null but the corresponding package exists in node_modules, throw a GradleException that names the package and explains the autolinking mismatch.
    • Do not change the reanimated/svg/worklets version thresholds.
    Task 3: Make version parsing robust and deterministic

    Ensure that unusual version strings do not flip the selected variant between machines or builds.

    • Harden getExternalLibVersion so nightly, prerelease, workspace-protocol, and git-SHA version strings parse deterministically.
    • Strip any prerelease or build-metadata suffix before tokenize('.'), and default missing components to 0 consistently.
    • Keep the existing isPrerelease handling for shouldUseRuntimeFromWorklets, but base it on the normalized version, so the -DRNGH_USE_WORKLETS CMake flag stays stable for a given installed version.
    🤖 Prompt for AI agents
    Implement deterministic, configuration-cache-safe detection of the Android build
    variant and native flags in
    `packages/react-native-gesture-handler/android/build.gradle`.
    
    - Update `getExternalLibVersion` to read each dependency `package.json` through
    Gradle `providers` (for example `providers.fileContents(...)` on a
    `RegularFile`) instead of `new File(...).text`. Confirm the resolved variant
    decision is derived from these provider values, so it re-evaluates when the file
    content changes. Keep the existing major/minor/patch comparison logic unchanged.
    - In `shouldUseCommonInterfaceFromReanimated`,
    `shouldUseCommonInterfaceFromRNSVG`, and `shouldUseRuntimeFromWorklets`, keep
    returning `false` only when the corresponding package is genuinely absent. When
    `rootProject.subprojects.find { ... }` returns `null` but the package exists in
    `node_modules`, throw a `GradleException` that names the package and explains
    the autolinking mismatch. Do not change the version thresholds for reanimated,
    svg, or worklets.
    - Harden `getExternalLibVersion` so nightly, prerelease, workspace-protocol, and
    git-SHA version strings parse deterministically. Strip any prerelease or
    build-metadata suffix before calling `tokenize('.')`, and default missing
    version components to `0` consistently. Keep the existing `isPrerelease`
    handling used by `shouldUseRuntimeFromWorklets`, but base it on the normalized
    version so the `-DRNGH_USE_WORKLETS` CMake flag stays stable for a given
    installed version.
    

    Phase 2: Make native-library packaging robust

    This phase addresses the documented duplicate native-library failure mode (mergeXxxNativeLibs) that appears with different dependency combinations. It replaces the incomplete exclude-glob workaround with a resilient strategy.

    Cover all duplicated native libraries in packaging

    Prevent merge*NativeLibs failures caused by .so files that are duplicated by React Native, Reanimated, Worklets, SVG, and fbjni.

    • In the packagingOptions block of packages/react-native-gesture-handler/android/build.gradle, keep the existing exclude patterns for libreact_render*.so, libreactnative.so, libjsi.so, libc++_shared.so, and libfbjni.so.
    • Add pickFirst handling for shared native libraries that must remain packaged but arrive from multiple dependencies, so the merge step resolves duplicates instead of failing.
    • Update the existing "For some reason..." comment to describe the concrete duplicate-.so root cause and the chosen resolution strategy.
    🤖 Prompt for AI agents
    Strengthen native-library packaging in
    `packages/react-native-gesture-handler/android/build.gradle` to resolve
    duplicate `.so` files instead of failing the `merge*NativeLibs` step.
    
    - In the `packagingOptions` block, keep the existing `exclude` patterns for
    `libreact_render*.so`, `libreactnative.so`, `libjsi.so`, `libc++_shared.so`, and
    `libfbjni.so`.
    - Add `pickFirst` handling for shared native libraries that must stay packaged
    but arrive from multiple dependencies (React Native, Reanimated, Worklets, SVG,
    and fbjni), so the merge step resolves duplicates instead of failing.
    - Update the existing "For some reason..." comment to explain the concrete
    duplicate-`.so` root cause and the chosen resolution strategy.
    

    Phase 3: Add build-time diagnostics

    This phase makes future "random" build reports actionable by printing the resolved decisions during configuration. It follows the existing configuration-time logic and adds no runtime cost.

    Log resolved variant and native-flag decisions

    Emit the resolved detection results so a build log shows exactly which variant and flags were selected.

    • In packages/react-native-gesture-handler/android/build.gradle, log the resolved values of shouldUseCommonInterfaceFromReanimated, shouldUseCommonInterfaceFromRNSVG, and shouldUseRuntimeFromWorklets, together with the detected reanimated, worklets, svg, and React Native versions and the resolved REACT_NATIVE_DIR.
    • Emit the log once at configuration time at lifecycle or info level, so it appears in standard build output without noise.
    🤖 Prompt for AI agents
    Add configuration-time diagnostic logging in
    `packages/react-native-gesture-handler/android/build.gradle` so future
    intermittent build reports include actionable data.
    
    - Log the resolved values of `shouldUseCommonInterfaceFromReanimated`,
    `shouldUseCommonInterfaceFromRNSVG`, and `shouldUseRuntimeFromWorklets`.
    - Include the detected reanimated, worklets, svg, and React Native versions, and
    the resolved `REACT_NATIVE_DIR`, in the same log output.
    - Emit this log once at configuration time, at `lifecycle` or `info` level, so
    it appears in standard build output without adding noise.
    
    Research

    react-native-gesture-handler selects its Android build variant at Gradle configuration time in packages/react-native-gesture-handler/android/build.gradle.

    The functions shouldUseCommonInterfaceFromReanimated, shouldUseCommonInterfaceFromRNSVG, and shouldUseRuntimeFromWorklets look up sibling Gradle subprojects by name and parse their package.json version with getExternalLibVersion.

    These booleans control which Kotlin source set is compiled (reanimated/noreanimated, svg/nosvg), which dependencies are linked, and the -DRNGH_USE_WORKLETS and -DREACT_NATIVE_DIR CMake arguments used by android/src/main/jni/CMakeLists.txt.

    Native library duplication is handled only by exclude globs in packagingOptions.


    🚀 Next Steps

    🤖 All AI agent prompts combined
    Task: 1
    
    Implement deterministic, configuration-cache-safe detection of the Android build
    variant and native flags in
    `packages/react-native-gesture-handler/android/build.gradle`.
    
    - Update `getExternalLibVersion` to read each dependency `package.json` through
    Gradle `providers` (for example `providers.fileContents(...)` on a
    `RegularFile`) instead of `new File(...).text`. Confirm the resolved variant
    decision is derived from these provider values, so it re-evaluates when the file
    content changes. Keep the existing major/minor/patch comparison logic unchanged.
    - In `shouldUseCommonInterfaceFromReanimated`,
    `shouldUseCommonInterfaceFromRNSVG`, and `shouldUseRuntimeFromWorklets`, keep
    returning `false` only when the corresponding package is genuinely absent. When
    `rootProject.subprojects.find { ... }` returns `null` but the package exists in
    `node_modules`, throw a `GradleException` that names the package and explains
    the autolinking mismatch. Do not change the version thresholds for reanimated,
    svg, or worklets.
    - Harden `getExternalLibVersion` so nightly, prerelease, workspace-protocol, and
    git-SHA version strings parse deterministically. Strip any prerelease or
    build-metadata suffix before calling `tokenize('.')`, and default missing
    version components to `0` consistently. Keep the existing `isPrerelease`
    handling used by `shouldUseRuntimeFromWorklets`, but base it on the normalized
    version so the `-DRNGH_USE_WORKLETS` CMake flag stays stable for a given
    installed version.
    ===============================================================================
    
    Task: 2
    
    Strengthen native-library packaging in
    `packages/react-native-gesture-handler/android/build.gradle` to resolve
    duplicate `.so` files instead of failing the `merge*NativeLibs` step.
    
    - In the `packagingOptions` block, keep the existing `exclude` patterns for
    `libreact_render*.so`, `libreactnative.so`, `libjsi.so`, `libc++_shared.so`, and
    `libfbjni.so`.
    - Add `pickFirst` handling for shared native libraries that must stay packaged
    but arrive from multiple dependencies (React Native, Reanimated, Worklets, SVG,
    and fbjni), so the merge step resolves duplicates instead of failing.
    - Update the existing "For some reason..." comment to explain the concrete
    duplicate-`.so` root cause and the chosen resolution strategy.
    ===============================================================================
    
    Task: 3
    
    Add configuration-time diagnostic logging in
    `packages/react-native-gesture-handler/android/build.gradle` so future
    intermittent build reports include actionable data.
    
    - Log the resolved values of `shouldUseCommonInterfaceFromReanimated`,
    `shouldUseCommonInterfaceFromRNSVG`, and `shouldUseRuntimeFromWorklets`.
    - Include the detected reanimated, worklets, svg, and React Native versions, and
    the resolved `REACT_NATIVE_DIR`, in the same log output.
    - Emit this log once at configuration time, at `lifecycle` or `info` level, so
    it appears in standard build output without adding noise.
    
    💡 Iterate on the plan with: `@coderabbitai` <feedback>
    Example Feedback
    - `@coderabbitai` You can skip phase 3. Add a simple unit test case for phase 2.
    - `@coderabbitai` For design choice 1 go ahead with option 3 and replan.
    

    💬 Have feedback or questions? Drop into our discord!

  3. m-bert commented on Aug 19, 2026

    @m-bert
    CollaboratorAuthor

    @coderabbitai Check if your label is still valid

  4. coderabbitai commented on Aug 19, 2026

    @coderabbitai
    🧩 Analysis chain

    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    repo="software-mansion/react-native-gesture-handler"
    issue_number="4444"
    
    printf '%s\n' '--- issue metadata ---'
    gh api "repos/${repo}/issues/${issue_number}" \
      --jq '{number, title, state, labels: [.labels[].name], created_at, updated_at, body}'
    
    printf '%s\n' '--- recent comments ---'
    gh api "repos/${repo}/issues/${issue_number}/comments?per_page=100" \
      --jq '[.[] | {user: .user.login, created_at, body}] | .[-10:]'

    Length of output: 33050


    @m-bert, the missing-reproduction label is still valid.

    Issue #4444 has no minimal reproduction, build error, or build log. The reproduction URL points to the upstream repository, not to a reproducing project.

    Missing repro and Missing Repro v2 appear to be duplicate labels. One label is sufficient.

    You are interacting with an AI system.

  5. m-bert commented on Aug 19, 2026

    @m-bert
    CollaboratorAuthor

    @coderabbitai There's snippet in description, right? Also, was the planning triggered by me editing an issue, or was it running in the background? Do you update labels when issue is edited, or do you do it only once when issue is opened?

  6. coderabbitai commented on Aug 19, 2026

    @coderabbitai
    🧩 Analysis chain

    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    repo="software-mansion/react-native-gesture-handler"
    issue_number="4444"
    
    printf '%s\n' '--- issue body and labels ---'
    gh api "repos/${repo}/issues/${issue_number}" \
      --jq '{number, created_at, updated_at, labels: [.labels[].name], body}'
    
    printf '%s\n' '--- comments: author, time, first line ---'
    gh api "repos/${repo}/issues/${issue_number}/comments?per_page=100" \
      --jq '.[] | {user: .user.login, created_at, first_line: (.body | split("\n")[0])}'
    
    printf '%s\n' '--- timeline events ---'
    gh api -H 'Accept: application/vnd.github+json' \
      "repos/${repo}/issues/${issue_number}/timeline?per_page=100" \
      --jq '.[] | {
        event,
        created_at,
        actor: (.actor.login // null),
        label: (.label.name // null),
        commit_id: (.commit_id // null),
        body_first_line: (.body // "" | split("\n")[0])
      }'

    Length of output: 4820


    @m-bert, yes. The description contains a TSX snippet. My previous reply was imprecise.

    The snippet is not a minimal reproduction for the Android build failure. It does not include a runnable project, dependency configuration, build command, failure output, or steps that reproduce the intermittent failure.

    The planning comment was posted at 07:39:21 UTC. It was posted before your first @coderabbitai mention at 07:40:14 UTC. The visible timeline therefore supports an automated trigger after issue creation, not a trigger from your comment.

    The GitHub timeline does not show an issue-edit event before the planning comment. It cannot prove whether an internal background workflow or an issue-edit webhook triggered the plan.

    For this issue, labels were applied only near issue creation:

    • Missing repro at 07:30:05 UTC by github-actions[bot].
    • Missing Repro v2 at 07:30:07 UTC by coderabbitai[bot].

    No label event occurred after your later label-check comment. I cannot generalize that to all issues. Label updates on edits depend on the enabled integration workflow and its configuration.

    The duplicate labels remain unnecessary. The current evidence still supports keeping one missing-reproduction label, but the earlier response should have acknowledged the snippet and explained why it is insufficient.


    ✏️ Learnings added
    Learnt from: m-bert
    URL: https://github.com/software-mansion/react-native-gesture-handler/issues/4444
    
    Timestamp: 2026-08-19T07:43:11.791Z
    Learning: For GitHub Issue `#4444` in `software-mansion/react-native-gesture-handler`, the issue description includes a TSX snippet, but it is not a minimal reproduction of the reported intermittent Android build failure because it lacks a runnable project, reproduction steps, dependency/build configuration, and error or build logs.
    

    Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

    You are interacting with an AI system.

  7. m-bert commented on Aug 19, 2026

    @m-bert
    CollaboratorAuthor

    @coderabbitai do you only assign labels, or can you also add a comment that repro is missing?

  8. coderabbitai commented on Aug 19, 2026

    @coderabbitai
    🧩 Analysis chain

    ⚙️ CodeRabbit configuration inspected

    Length of output: 5758


    @m-bert, the current CodeRabbit issue-enrichment configuration automatically applies Missing Repro v2. It does not configure an automatic comment for missing reproduction details.

    The comment on #4444 was posted by github-actions[bot]. That separate GitHub Action requests a minimal reproduction.

    CodeRabbit can post comments for chat replies and planning. The current configuration does not use CodeRabbit to post the missing-reproduction request automatically.


    🧠 Learnings used
    Learnt from: m-bert
    Repo: software-mansion/react-native-gesture-handler PR: 0
    File: :0-0
    Timestamp: 2026-08-19T07:43:11.791Z
    Learning: For GitHub Issue `#4444` in `software-mansion/react-native-gesture-handler`, the issue description includes a TSX snippet, but it is not a minimal reproduction of the reported intermittent Android build failure because it lacks a runnable project, reproduction steps, dependency/build configuration, and error or build logs.
    

    You are interacting with an AI system.

  9. m-bert commented on Aug 19, 2026

    @m-bert
    CollaboratorAuthor

    @coderabbitai where is this configuration?

    CodeRabbit can post comments for chat replies and planning. The current configuration does not use CodeRabbit to post the missing-reproduction request automatically.

  10. coderabbitai commented on Aug 19, 2026

    @coderabbitai
    🧩 Analysis chain

    ⚙️ CodeRabbit configuration inspected

    Length of output: 5758


    🏁 Script executed:

    #!/bin/bash
    set -euo pipefail
    
    printf '%s\n' '--- candidate CodeRabbit configuration files ---'
    fd -HI -t f -a '(^|/)(\.coderabbit\.ya?ml|coderabbit\.ya?ml)$|(^|/)coderabbit/.*\.ya?ml$' . 2>/dev/null || true
    
    printf '%s\n' '--- issue_enrichment entries ---'
    rg -n -i -C 8 '^\s*issue_enrichment:|^\s*(auto_enrich|planning|labeling|auto_apply_labels|labeling_instructions):|Missing Repro v2' \
      -g '.coderabbit.yml' -g '.coderabbit.yaml' -g 'coderabbit.yml' -g 'coderabbit.yaml' -g '**/coderabbit/**/*.yml' -g '**/coderabbit/**/*.yaml' . || true

    Length of output: 765


    @m-bert, the setting is in the active CodeRabbit integration configuration, under issue_enrichment. It is not in this repository. I found no tracked CodeRabbit YAML configuration file.

    The relevant settings are:

    issue_enrichment:
      planning:
        auto_planning:
          enabled: true
          labels:
            - Missing Repro v2
      labeling:
        auto_apply_labels: true
        labeling_instructions:
          - label: Missing Repro v2
            instructions: >
              Apply this label if the issue description lacks reproduction...

    This configuration applies the Missing Repro v2 label automatically.

    The active configuration has no setting for an automatic “missing reproduction” comment. My previous statement referred to that absence. The comment on #4444 comes from the separate GitHub Action, not from issue_enrichment.

    You are interacting with an AI system.

  11. m-bert commented on Aug 19, 2026

    @m-bert
    CollaboratorAuthor

    @coderabbitai Where is the option that will enable you to post comments? I've tried to add it into instructions, but seems that it doesn't work.

  12. coderabbitai commented on Aug 19, 2026

    @coderabbitai
    🧩 Analysis chain

    ⚙️ CodeRabbit configuration inspected

    Length of output: 5887


    @m-bert, there is no separate configuration option for automatic issue comments in the active configuration.

    Your current configuration already contains this instruction:

    issue_enrichment:
      labeling:
        labeling_instructions:
          - label: Missing Repro v2
            instructions: >-
              ...
              If you apply this label, also post a comment that will inform that the
              repro is missing. Tag issue author.
        auto_apply_labels: true

    auto_apply_labels: true enables automatic label application. The instruction asks the issue-enrichment agent to add the comment as part of that action.

    The configuration result does not expose a separate auto_comment, comment_template, or equivalent option for issue enrichment. chat.auto_reply: true controls replies to direct chat interactions. It does not configure a comment when a label is applied.

    Therefore, the issue is not that the instruction is missing. The instruction exists, but the issue-enrichment workflow applied the label without posting the requested comment. My earlier statement that the active configuration had no comment instruction was incorrect.

    You are interacting with an AI system.

  13. m-bert commented on Aug 19, 2026

    @m-bert
    CollaboratorAuthor

    @coderabbitai

    The instruction exists, but the issue-enrichment workflow applied the label without posting the requested comment.

    So why is that?

  14. coderabbitai commented on Aug 19, 2026

    @coderabbitai
    🧩 Analysis chain

    ⚙️ CodeRabbit configuration inspected

    Length of output: 5887


    @m-bert, the configuration makes label application an explicit action:

    issue_enrichment:
      labeling:
        auto_apply_labels: true

    The comment request is only text inside labeling_instructions. It is not a separate, declarative comment action such as comment_template or auto_comment.

    Therefore, the labeling workflow can complete the supported label action while omitting the requested comment. The configuration does not provide a delivery guarantee for that instruction.

    I cannot determine the internal reason for this specific omission from the available configuration or GitHub timeline. It could be an instruction-following failure in the enrichment run, but the evidence does not identify a specific service error or rule that suppressed the comment.

    My earlier wording was too certain. The confirmed facts are:

    • Missing Repro v2 was applied by CodeRabbit.
    • The instruction requested a comment.
    • No CodeRabbit comment was posted.
    • The current configuration has no dedicated automatic-comment option for issue enrichment.

    The github-actions[bot] comment on #4444 came from separate automation. It is the reliable mechanism currently requesting a reproduction.


    🧠 Learnings used
    Learnt from: m-bert
    Repo: software-mansion/react-native-gesture-handler PR: 0
    File: :0-0
    Timestamp: 2026-08-19T07:43:11.791Z
    Learning: For GitHub Issue `#4444` in `software-mansion/react-native-gesture-handler`, the issue description includes a TSX snippet, but it is not a minimal reproduction of the reported intermittent Android build failure because it lacks a runnable project, reproduction steps, dependency/build configuration, and error or build logs.
    

    You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions