Home > Internal > Sessions > PR #269 Debugging Session
PR #269 Debugging Session: Firebase BOM Resolution Crisis
Date: 2025-11-18 (Week 28)
Duration: ~2 hours, 6 build attempts
Agent: Orchestrator (Agent O)
Outcome: ✅ Resolved - Stay on Firebase BOM 33.0.0, discovered KTX deprecation
Key Discovery: Firebase BOM 34.0.0+ removed all
-ktxlibraries (July 2025)
Session Overview
Emergency debugging session for PR #269 (Gradle dependency updates) that encountered build failures after updating Firebase BOM. What started as a simple dependency update spiraled into a deep investigation of Gradle version catalogs, BOM behavior, and Firebase’s deprecation of KTX modules.
Learning Value: This session demonstrates the importance of checking external dependency release notes when builds fail unexpectedly.
Initial Context
PR #269 Objective
Goal: Update Gradle dependencies to latest versions
Scope:
- Update Compose BOM
- Update Firebase BOM
- Move Firebase dependencies to version catalog (better maintainability)
- Update other Android dependencies
Expected Risk: Low - routine dependency updates
Build Attempt #1: Compose BOM Fix
Initial Problem
Copilot Alert:
Compose BOM version inconsistency detected
Changes Made
File: gradle/libs.versions.toml
[versions]
- compose-bom = "2024.06.00"
+ compose-bom = "2025.11.00"
[libraries]
- compose-bom = "androidx.compose:compose-bom:2024.06.00" # String notation, version duplicated
+ compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" } # Object notation, version referenceFile: app/build.gradle.kts
dependencies {
implementation(platform(libs.compose.bom)) # Now uses version catalog
// ... compose dependencies
}Result
./gradlew clean buildOutput:
> Task :app:processDebugManifest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Could not find com.google.firebase:firebase-analytics-ktx:.
Required by:
project :app
> Could not find com.google.firebase:firebase-crashlytics-ktx:.
Required by:
project :app
Observation: Empty version strings (:firebase-analytics-ktx:. with nothing after the final :)
Analysis
- Compose BOM fix didn’t cause this (Firebase issue)
- Firebase BOM updated to 34.6.0 in same commit
- Gradle can’t find versions for Firebase KTX libraries
- Suspected version catalog syntax issue
Commit: 72bb86ce - fix: Use version catalog for Compose BOM and Firebase dependencies
Build Attempt #2: Firebase Version Catalog Syntax
Hypothesis
Version catalog syntax for Firebase might be incorrect. Maybe BOM-managed dependencies need different syntax.
Investigation
Checked version catalog:
[versions]
firebase-bom = "34.6.0"
[libraries]
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx" } # No version - BOM provides it
firebase-analytics-ktx = { group = "com.google.firebase", name = "firebase-analytics-ktx" }Build script:
dependencies {
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.auth.ktx)
implementation(libs.firebase.analytics.ktx)
}Researched:
- Gradle documentation on version catalogs + BOMs
- Pattern matched official examples
Conclusion
Syntax looks correct according to Gradle docs. BOM should provide versions for individual libraries.
Result
No changes made - syntax appeared correct.
Build Attempt #3: Add Missing Library to Catalog
Hypothesis
Maybe firebase-crashlytics-ktx was missing from version catalog?
Changes Made
File: gradle/libs.versions.toml
[libraries]
firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx" }
firebase-analytics-ktx = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
+ firebase-crashlytics-ktx = { group = "com.google.firebase", name = "firebase-crashlytics-ktx" }Result
./gradlew clean buildSame error:
> Could not find com.google.firebase:firebase-analytics-ktx:.
> Could not find com.google.firebase:firebase-crashlytics-ktx:.
Analysis
Adding the catalog entry didn’t help. Both libraries still have empty versions.
Commit: e3fee2fd - fix: Add firebase-crashlytics-ktx to version catalog
Build Attempt #4: KSP Version Compatibility
Hypothesis
Noticed KSP version might be incompatible with Kotlin 2.2.21.
Investigation
Current versions:
- Kotlin: 2.2.21
- KSP: 2.2.0-2.0.2
KSP versioning scheme: {KSP version}-{Kotlin version}
Problem: KSP 2.2.0 might not work with Kotlin 2.2.21
Changes Made
File: gradle/libs.versions.toml
[versions]
- ksp = "2.2.0-2.0.2"
+ ksp = "2.2.21-1.0.29" # Match Kotlin 2.2.21Note: Later discovered this version doesn’t exist. Should be 2.2.21-2.0.4.
Result
./gradlew clean buildNew error:
> Could not find com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.2.21-1.0.29.
Firebase errors still present (but hidden by KSP error)
Analysis
- KSP version doesn’t exist
- Even if it did, probably unrelated to Firebase issue
- Red herring
Commit: 9589d762 - fix: Update KSP to 2.2.21-1.0.29 for Kotlin 2.2.21 compatibility (WRONG VERSION)
Build Attempt #5: Downgrade Firebase BOM
Hypothesis
Maybe Firebase BOM 34.6.0 is too new? Try older 34.x version.
Changes Made
File: gradle/libs.versions.toml
[versions]
- firebase-bom = "34.6.0"
+ firebase-bom = "34.3.0" # Slightly olderAdditional Actions
./gradlew clean
rm -rf ~/.gradle/caches/ # Nuclear option - clear all Gradle caches
./gradlew buildResult
Same Firebase errors:
> Could not find com.google.firebase:firebase-analytics-ktx:.
> Could not find com.google.firebase:firebase-crashlytics-ktx:.
Analysis
- BOM version doesn’t matter (tried 34.6.0, 34.3.0, both fail)
- Cache clearing doesn’t help
- Problem is deeper than version selection
Pattern emerging: All Firebase BOM 34.x versions fail with KTX libraries
Breakthrough: Compare with Main Branch
Investigation Method
Checkout main branch and examine working configuration:
git stash
git checkout main
cat app/build.gradle.kts | grep firebaseDiscoveries
Main branch uses:
// File: app/build.gradle.kts
dependencies {
// Hardcoded Firebase BOM version
implementation(platform("com.google.firebase:firebase-bom:33.0.0"))
// String literals, NOT version catalog references
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.google.firebase:firebase-firestore-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-crashlytics-ktx")
}Key differences from PR branch:
- BOM version: 33.0.0 (not 34.x)
- Dependency style: String literals (not version catalog)
- Configuration: Hardcoded (not centralized)
Initial Conclusion
Maybe version catalog approach is incompatible with Firebase BOM?
Test: Try BOM 33.0.0 with Version Catalog
[versions]
firebase-bom = "33.0.0" # Same as main
[libraries]
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx" }./gradlew clean buildResult: ✅ BUILD SUCCESSFUL
Revelation
It’s not the version catalog syntax - it’s the BOM version!
- BOM 33.0.0 works with KTX libraries
- BOM 34.x fails with KTX libraries
- Something changed between 33.x and 34.x
Deep Investigation: Firebase Release Notes
Research Questions
- Why does Firebase BOM 34.x not provide versions for
-ktxlibraries? - Is this intentional or a bug?
- What changed between BOM 33.x and 34.x?
Research Process
Searched:
- Firebase Android release notes
- Firebase BOM changelog
- Google for “firebase ktx deprecated”
- Stack Overflow threads
The Discovery
Firebase Release Notes (July 2025):
Firebase BoM v34.0.0
In July 2025, Firebase stopped releasing new versions of the KTX modules, and removed the KTX modules from the Firebase BoM (starting with BoM v34.0.0).
Migration: The Kotlin extensions are now included in the main modules. To use the Kotlin extensions, remove the
-ktxsuffix from your Firebase dependencies.Example:
- Before:
com.google.firebase:firebase-auth-ktx- After:
com.google.firebase:firebase-authAll KTX APIs remain available in the main modules. No code changes required.
Implications
- Firebase deprecated KTX modules entirely
- BOM 34.0.0+ doesn’t include
-ktxlibraries - This is intentional, not a bug
- Our version catalog syntax was correct all along
- We were referencing libraries that no longer exist in the BOM
Solution Decision
Options
Option A: Migrate to Firebase BOM 34.x (non-KTX)
- Remove
-ktxsuffixes from all Firebase dependencies - Update version catalog entries
- Test all Firebase functionality
- Effort: Medium
- Risk: Low (no code changes needed)
- Timeline: Could be done now
Option B: Stay on Firebase BOM 33.0.0 (KTX)
- Keep existing
-ktxdependencies - Revert to hardcoded Firebase dependencies (match main)
- Defer migration to future PR
- Effort: Low
- Risk: Very low (matches working main branch)
- Timeline: Immediate
Decision: Option B (Stay on BOM 33.0.0)
Rationale:
- PR #269 goal is dependency updates, not Firebase migration
- BOM 33.0.0 is stable and working
- Minimize scope of PR (already complex)
- Can migrate to 34.x in dedicated future PR
- Unblock PR #269 and PR #271 (both blocked)
Build Attempt #6: Final Solution
Changes Made
File: app/build.gradle.kts
dependencies {
// Revert to hardcoded Firebase dependencies matching main
- implementation(platform(libs.firebase.bom))
- implementation(libs.firebase.auth.ktx)
- implementation(libs.firebase.firestore.ktx)
- implementation(libs.firebase.analytics.ktx)
- implementation(libs.firebase.crashlytics.ktx)
+ implementation(platform("com.google.firebase:firebase-bom:33.0.0"))
+ implementation("com.google.firebase:firebase-auth-ktx")
+ implementation("com.google.firebase:firebase-firestore-ktx")
+ implementation("com.google.firebase:firebase-analytics-ktx")
+ implementation("com.google.firebase:firebase-crashlytics-ktx")
implementation("com.google.android.gms:play-services-auth:20.7.0")
}File: gradle/libs.versions.toml
# Removed Firebase entries (not using version catalog for Firebase yet)
- [versions]
- firebase-bom = "34.6.0"
-
- [libraries]
- firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
- firebase-auth-ktx = { group = "com.google.firebase", name = "firebase-auth-ktx" }
- firebase-analytics-ktx = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
- firebase-crashlytics-ktx = { group = "com.google.firebase", name = "firebase-crashlytics-ktx" }Result
./gradlew clean buildOutput:
BUILD SUCCESSFUL in 2m 34s
142 actionable tasks: 142 executed
✅ SUCCESS!
Verification
# Android build
./gradlew assembleDebug assembleRelease
✅ Both APKs build successfully
# Unit tests
./gradlew test
✅ All tests pass
# iOS framework
./gradlew linkDebugFrameworkIosSimulatorArm64
✅ iOS framework buildsCommit: 0d2dd5aa - fix: Revert to hardcoded Firebase BOM 33.0.0
Post-Resolution: iOS Swift Type Errors
New Problem
After Android build succeeded, attempted iOS build in Xcode:
Xcode errors:
TournamentListViewModel.swift:158:97 Cannot convert value of type 'Int' to expected argument type 'Int32'
TournamentListViewModel.swift:159:97 Cannot convert value of type 'Int' to expected argument type 'Int32'
TournamentListViewModel.swift:173:94 Cannot convert value of type 'Int' to expected argument type 'Int32'
Root Cause
Kotlin’s Int type (32-bit) maps to Swift’s Int32, not Swift’s Int (platform-dependent, 64-bit on modern devices).
Solution
File: iosApp/ArcheryApprentice/ArcheryApprentice/TournamentListViewModel.swift
// Line 158
- maxScoreCorrections: sec["maxScoreCorrections"] as? Int ?? 3,
+ maxScoreCorrections: sec["maxScoreCorrections"] as? Int32 ?? 3,
// Line 159
- correctionTimeLimit: sec["correctionTimeLimit"] as? Int ?? 300,
+ correctionTimeLimit: sec["correctionTimeLimit"] as? Int32 ?? 300,
// Line 173
- dataRetentionDays: priv["dataRetentionDays"] as? Int ?? 90
+ dataRetentionDays: priv["dataRetentionDays"] as? Int32 ?? 90Result
✅ iOS build succeeded
Commit: fe1a2403 - fix: Change Int to Int32 for Kotlin framework compatibility
Related: Kotlin-Swift Type Interoperability Guide
Post-Resolution: CI Runner Selection Issues
New Problem (Session Continuation)
Context: Self-hosted runner offline overnight, needed GitHub-hosted runner
Attempted: Pushed empty commit with [github] flag to force GitHub runner
Result: Workflow failed to detect flag
Investigation
Found 4 issues:
-
decide_runnerjob hardcoded to self-hosted- Decision logic runs on self-hosted runner
- If self-hosted offline, decision can’t run (chicken-egg problem)
-
powershellvspwshon Linux runners- Windows PowerShell (
powershell) doesn’t exist on Linux - PowerShell Core (
pwsh) required for cross-platform
- Windows PowerShell (
-
Stale PR title in GitHub Actions event data
- Workflow checked
github.event.pull_request.title - Value cached at workflow start (before
[github]added to title)
- Workflow checked
-
Merge commits in PR context
git log -1showed merge commit, not actual commit message- Commit message flags not detected
Solutions Applied
File: .github/workflows/android-ci.yml
decide_runner:
name: Decide Runner
runs-on: ubuntu-latest # Changed from self-hosted (always available)
steps:
- name: Determine runner to use
id: decide
shell: pwsh # Changed from powershell (works on Linux)
run: |
# Fetch current PR title via API (not stale event data)
$prTitle = gh pr view ${{ github.event.pull_request.number }} --json title -q .title
# Priority 1: Commit message flags
$commitMessage = git log -1 --pretty=%B
if ($commitMessage -match '\[github\]') {
echo "runner=github" >> $env:GITHUB_OUTPUT
} elseif ($commitMessage -match '\[self-hosted\]') {
echo "runner=self-hosted" >> $env:GITHUB_OUTPUT
}
# Priority 2: PR title flags (current, not cached)
elseif ($prTitle -match '\[github\]') {
echo "runner=github" >> $env:GITHUB_OUTPUT
}
# Priority 3: Day-based default
else {
# ... day logic
}Priority System:
- Commit message flags →
[github],[self-hosted],[skip-ci] - PR title flags (fetched via API)
- Manual workflow_dispatch input
- Day-based default (days 1-25: self-hosted, 26-31: github)
Result
✅ Workflow correctly detects [github] flag and runs on GitHub-hosted runners
Commits:
7f779915- ci: Force GitHub-hosted runner + fix decide_runner to ubuntu-latestdc3f0b9b- fix: Use pwsh instead of powershell for Linux runner5c6c047b- fix: Use PR title as source of truth for runner selection48c4d7e3- fix: Fetch current PR title via API and check commit message priority
Related: GitHub Actions Dynamic Runner Selection
Session Summary
Timeline
| Time | Event |
|---|---|
| 00:00 | Start: PR #269 Firebase BOM update |
| 00:15 | Attempt #1: Fix Compose BOM → Firebase errors appear |
| 00:30 | Attempt #2: Verify version catalog syntax |
| 00:45 | Attempt #3: Add missing crashlytics entry → still fails |
| 01:00 | Attempt #4: Fix KSP version → wrong version, red herring |
| 01:15 | Attempt #5: Downgrade Firebase BOM 34.6.0 → 34.3.0 → still fails |
| 01:30 | Breakthrough: Compare with main branch → BOM 33.0.0 works |
| 01:45 | Research Firebase release notes → KTX deprecated in BOM 34.0.0! |
| 02:00 | Attempt #6: Revert to BOM 33.0.0 hardcoded → ✅ SUCCESS |
| 02:15 | iOS build: Fix Int → Int32 type conversions → ✅ iOS SUCCESS |
| 02:30 | CI runner workflow fixes → ✅ Dynamic runner selection working |
| 02:45 | Session complete |
Commits
72bb86ce- fix: Use version catalog for Compose BOM and Firebase dependencies9589d762- fix: Update KSP to 2.2.21-1.0.29 (WRONG, red herring)e3fee2fd- fix: Add firebase-crashlytics-ktx to version catalog0d2dd5aa- fix: Revert to hardcoded Firebase BOM 33.0.0 (SOLUTION)fe1a2403- fix: Change Int to Int32 for Kotlin framework compatibility (iOS)7f779915- ci: Force GitHub-hosted runner + fix decide_runner to ubuntu-latestdc3f0b9b- fix: Use pwsh instead of powershell for Linux runner5c6c047b- fix: Use PR title as source of truth for runner selection48c4d7e3- fix: Fetch current PR title via API and check commit message priority
Lessons Learned
1. Check External Dependency Release Notes
Lesson: When dependencies fail unexpectedly, check release notes before debugging tooling.
What Happened:
- Assumed Gradle or version catalog issue
- Spent 90 minutes debugging configuration
- Real issue: Firebase deprecated libraries (external change)
Should Have Done:
- Searched “firebase bom 34 release notes” within first 15 minutes
- Would have found KTX deprecation immediately
2. Compare with Known-Working State Early
Lesson: Compare with working configuration as soon as unusual errors appear.
What Happened:
- Tried 5 different fixes before comparing with main
- Comparison immediately revealed BOM version difference
Should Have Done:
- Compare with main branch after attempt #2 (not #5)
- Would have saved 45 minutes
3. Version Catalog Syntax Was Never Wrong
Lesson: Don’t blame tools without evidence.
What Happened:
- Suspected version catalog syntax issue
- Researched Gradle docs, Stack Overflow
- Syntax was correct all along
Reality:
- Version catalog + BOM pattern works perfectly
- Problem was referencing libraries that don’t exist in BOM 34.x
- Tools worked as designed
4. Red Herrings Are Part of Debugging
Lesson: Not every investigated issue is related to the problem.
Red Herrings in This Session:
- KSP version compatibility (unrelated)
- Gradle cache corruption (not the cause)
- Version catalog syntax (correct all along)
- Network/Maven issues (not a factor)
Accept Reality:
- Red herrings are normal in debugging
- Document them to help future developers avoid same paths
- Each eliminated possibility brings you closer to root cause
5. Breaking Changes Cascade
Lesson: Breaking changes in dependencies can look like configuration issues.
What Happened:
- Firebase removed libraries from BOM (breaking change)
- Our build failed with cryptic “empty version” error
- Error message didn’t indicate external dependency change
Takeaway:
- Always consider external dependency changes
- Check release notes when upgrading
- Major version bumps (33.x → 34.x) are red flags
Recommendations for Future PRs
1. Dependency Update Strategy
Before Updating:
- Read release notes for major version bumps
- Check for deprecation announcements
- Search for “[library name] [new version] breaking changes”
During Update:
- Update one category at a time (e.g., Firebase separate from Compose)
- Build and test after each category
- Commit working states incrementally
After Update:
- Test all platforms (Android + iOS)
- Run full test suite
- Verify CI workflows work
2. Firebase BOM Migration Plan
When Ready to Migrate to BOM 34.x:
Step 1: Create Dedicated PR
- Title:
deps: Migrate Firebase to non-KTX modules (BOM 34.x+) - No other changes in same PR
Step 2: Update All Firebase Dependencies
- implementation("com.google.firebase:firebase-auth-ktx")
+ implementation("com.google.firebase:firebase-auth")Step 3: Test Thoroughly
- Firebase Auth flows
- Firestore queries
- Analytics events
- Crashlytics reporting
Step 4: Document Migration
- Note in PR description
- Update README if Firebase version documented
- Add to CHANGELOG
3. Version Catalog Adoption
Consider using version catalog for Firebase once migrated to BOM 34.x:
Benefits:
- Centralized version management
- Type-safe references
- Easier future updates
Implementation:
[versions]
firebase-bom = "34.6.0"
[libraries]
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
firebase-auth = { group = "com.google.firebase", name = "firebase-auth" }
firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore" }Related Documentation
Technical Knowledge:
- Firebase KTX Deprecation Guide
- Gradle Version Catalogs + BOM Integration
- Kotlin-Swift Type Interoperability
- GitHub Actions Dynamic Runner Selection
External Resources:
- Firebase Android Release Notes
- Gradle Version Catalogs Documentation
- GitHub Issue #17117 - Version Catalogs + BOMs
Conclusion
This session demonstrates that build failures aren’t always configuration issues. External dependencies change, and those changes can manifest as cryptic errors. The key debugging skills demonstrated:
- Systematic elimination - Tried multiple hypotheses methodically
- Comparison with working state - Identified BOM version difference
- External research - Found Firebase deprecation announcement
- Pragmatic decision-making - Chose low-risk solution (stay on BOM 33.0.0)
- Complete resolution - Fixed Android, iOS, and CI issues
Final Status: PR #269 unblocked, builds passing, ready for review
Session End: 2025-11-18 02:45 Agent: Orchestrator (Agent O) Status: Complete ✅ Week: 28