# FocusRequester "Not Initialized" — Systemetic Fix Methodology

## Audit date: 2026-06-14

### Root Cause
Bare `requestFocus()` calls in `LaunchedEffect` blocks that fire before the target composable node is laid out. Compose throws `IllegalStateException("FocusRequester is not initialized")`.

### Audit Command
```bash
grep -rn '\.requestFocus()' --include='*.kt' app/src/main/java/
```

### Classification
Each hit falls into one of three categories:

| Context | Fix | Count |
|---------|-----|-------|
| Inside `LaunchedEffect` | Replace with `.requestFocusAfterFrames()` | 25+ calls across 14+ files |
| Inside synchronous callback (onFocusChanged, BackHandler, onPreviewKeyEvent) | Wrap in `runCatching { ... }` or `try { ... } catch (_: Exception) {}` | 3 calls |
| Already wrapped in `runCatching { ... requestFocus() }` INSIDE LaunchedEffect | Can upgrade to `.requestFocusAfterFrames()` (cleaner) | ~15 calls across 10 files |

### Pattern — Convert `runCatching { requestFocus() }` in LaunchedEffect
```kotlin
// Before
LaunchedEffect(Unit) {
    runCatching { historyButtonRequester.requestFocus() }
}

// After
LaunchedEffect(Unit) {
    historyButtonRequester.requestFocusAfterFrames()
}
```

### Files Fixed (18 total)

| File | Lines | Fix |
|---|---|---|
| `player/NuvioSourceSidePanel.kt` | 88, 90, 93 | `requestFocus()` → `requestFocusAfterFrames()` |
| `player/NuvioSelectionPanels.kt` | 84-87, 154-155, 246-248 | 8 calls → `requestFocusAfterFrames()` |
| `player/SkipIntroButton.kt` | 122 | `try{requestFocus()}` → `requestFocusAfterFrames()` |
| `player/PlayerOverlayScaffold.kt` | 53 | `runCatching{requestFocus()}` → `requestFocusAfterFrames()` |
| `player/NextEpisodeEndPromptOverlay.kt` | 70 | Same upgrade |
| `player/PlayerScreen.kt` | 133 | Same upgrade |
| `profiles/ProfileSelectScreen.kt` | 108 | Same upgrade |
| `profiles/ProfileDetailScreen.kt` | 88 | Same upgrade |
| `profiles/ProfileCreateScreen.kt` | 93 | Same upgrade |
| `profiles/KidsProfileScreen.kt` | 80 | Same upgrade |
| `search/SearchScreen.kt` | 80, 124 | Line 80 → `requestFocusAfterFrames()`, line 124 → `try{requestFocus()}` |
| `catalog/CatalogManagerScreen.kt` | 84 | `requestFocus()` → `requestFocusAfterFrames()` |
| `components/ResolverOverlay.kt` | 196 | `requestFocus()` → `requestFocusAfterFrames()` |
| `components/PosterOptionsDialog.kt` | 43 | `runCatching{requestFocus()}` → `requestFocusAfterFrames()` |
| `settings/SettingsScreen.kt` | 164, 179 | Already `requestFocusAfterFrames()` |
| `placeholder/PlaceholderScreen.kt` | 47 | Already `requestFocusAfterFrames()` |

### Verification
After fixing all files, run:
```bash
grep -rn '\.requestFocus()' --include='*.kt' app/src/main/java/
# Only callback-based bare calls should remain (in try/catch)
```
