title: Android Paging 3 PagingDataAdapter.refresh() followed by retry() causes IllegalStateException: Cannot coerce hint when no pages have loaded
body: <p>I'm implementing paging from network + database cache using the new <a href="https://developer.android.com/topic/libraries/architecture/paging/v3-overview" rel="nofollow noreferrer">Paging 3</a> library. My implementation is similar to <a href="https://codelabs.developers.google.com/codelabs/android-paging" rel="nofollow noreferrer">Android Paging codelab</a> sample. The most significant difference is that I want to show DB data immediately while network data is loading. I've implemented a <code>RemoteMediator</code> and use a <code>PagingSource</code> provided by Room database.</p>
  <pre class="lang-kotlin prettyprint-override"><code>@Dao
  interface FooDao {
    ...
    
    @Query(&quot;SELECT * FROM foo&quot;)
    fun getFooSource(): PagingSource&lt;Int, Foo&gt;
  }
  </code></pre>
  <p>By default no data is displayed in the <code>RecycleView</code> if there's no network connection. To display DB data from <code>PagingSource</code> immediately my <code>RemoteMediator</code> uses <code>InitializeAction.SKIP_INITIAL_REFRESH</code> and it solves the problem.</p>
  <pre class="lang-kotlin prettyprint-override"><code>class MyRemoteMediator(...) : RemoteMediator&lt;Int, Foo&gt;() {
    ...
  
    override suspend fun initialize(): InitializeAction {
      return InitializeAction.SKIP_INITIAL_REFRESH
    }
  }
  </code></pre>
  <p>Now DB data is displayed immediately, but network data isn't loaded so I use <code>PagingDataAdapter.refresh()</code> method to trigger the request. I don't sure where is the proper place for the <code>refresh()</code> call, it doesn't work if I call it inside <code>Fragment.onCreate()</code> for example, so lets delay the call. I don't think it's a right way, just for an example:</p>
  <pre class="lang-kotlin prettyprint-override"><code>class MyFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
  
      lifecycleScope.launch {
        delay(1000)
        adapter.refresh()
      }
    }
  }
  </code></pre>
  <p>Now it works almost as expected, DB data is displayed immediately and <code>RemoteMediator</code> loads data from the network and updates the database. The only problem, if there's no internet access <code>RemoteMediator</code> request fails and returns <code>MediatorResult.Error</code>. If I retry the request later using <code>PagingDataAdapter.retry()</code> method I get the following error when I scroll the list:</p>
  <pre><code>E/AndroidRuntime: FATAL EXCEPTION: main
      Process: com.icesmith.tvprogramepg, PID: 6381
      java.lang.IllegalStateException: Cannot coerce hint when no pages have loaded
          at androidx.paging.PagerState.withCoercedHint$paging_common(PagerState.kt:313)
          at androidx.paging.PageFetcherSnapshot.doLoad(PageFetcherSnapshot.kt:369)
          at androidx.paging.PageFetcherSnapshot$startConsumingHints$2$invokeSuspend$$inlined$collect$1.emit(Collect.kt:137)
          at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:59)
          at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:11)
          at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
          at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
          at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:69)
          at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:184)
          at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
          at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:306)
          at kotlinx.coroutines.CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:393)
          at kotlinx.coroutines.channels.AbstractChannel$ReceiveElement.completeResumeReceive(AbstractChannel.kt:888)
          at kotlinx.coroutines.channels.ConflatedChannel.offerInternal(ConflatedChannel.kt:62)
          at kotlinx.coroutines.channels.ConflatedBroadcastChannel$Subscriber.offerInternal(ConflatedBroadcastChannel.kt:295)
          at kotlinx.coroutines.channels.ConflatedBroadcastChannel.offerInternal(ConflatedBroadcastChannel.kt:257)
          at kotlinx.coroutines.channels.ConflatedBroadcastChannel.offer(ConflatedBroadcastChannel.kt:238)
          at androidx.paging.PageFetcherSnapshot.addHint(PageFetcherSnapshot.kt:179)
          at androidx.paging.PageFetcher$PagerUiReceiver.addHint(PageFetcher.kt:108)
          at androidx.paging.PagingDataDiffer.get(PagingDataDiffer.kt:113)
          at androidx.paging.AsyncPagingDataDiffer.getItem(AsyncPagingDataDiffer.kt:241)
          at androidx.paging.PagingDataAdapter.getItem(PagingDataAdapter.kt:150)
          at com.icesmith.tvprogramepg.fragment.channellist.ChannelAdapter.onBindViewHolder(ChannelAdapter.kt:31)
          at com.icesmith.tvprogramepg.fragment.channellist.ChannelAdapter.onBindViewHolder(ChannelAdapter.kt:13)
          at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7163)
          at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7243)
          at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6110)
          at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6376)
          at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
          at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
          at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
          at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
          at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
          at android.os.Handler.handleCallback(Handler.java:883)
          at android.os.Handler.dispatchMessage(Handler.java:100)
          at android.os.Looper.loop(Looper.java:214)
          at android.app.ActivityThread.main(ActivityThread.java:7356)
          at java.lang.reflect.Method.invoke(Native Method)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
  
  </code></pre>