{"record":{"id":"e3a13fe75f0aaea9","repo":"google/ExoPlayer","slug":"missing-implementation-to-handle-command-prepare","errorCode":null,"errorMessage":"Missing implementation to handle COMMAND_PREPARE","messagePattern":"Missing implementation to handle COMMAND_PREPARE","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java","lineNumber":2940,"sourceCode":"   * @return A {@link ListenableFuture} indicating the completion of all immediate {@link State}\n   *     changes caused by this call.\n   */\n  @ForOverride\n  protected ListenableFuture<?> handleSetPlayWhenReady(boolean playWhenReady) {\n    throw new IllegalStateException(\"Missing implementation to handle COMMAND_PLAY_PAUSE\");\n  }\n\n  /**\n   * Handles calls to {@link Player#prepare}.\n   *\n   * <p>Will only be called if {@link Player#COMMAND_PREPARE} is available.\n   *\n   * @return A {@link ListenableFuture} indicating the completion of all immediate {@link State}\n   *     changes caused by this call.\n   */\n  @ForOverride\n  protected ListenableFuture<?> handlePrepare() {\n    throw new IllegalStateException(\"Missing implementation to handle COMMAND_PREPARE\");\n  }\n\n  /**\n   * Handles calls to {@link Player#stop}.\n   *\n   * <p>Will only be called if {@link Player#COMMAND_STOP} is available.\n   *\n   * @return A {@link ListenableFuture} indicating the completion of all immediate {@link State}\n   *     changes caused by this call.\n   */\n  @ForOverride\n  protected ListenableFuture<?> handleStop() {\n    throw new IllegalStateException(\"Missing implementation to handle COMMAND_STOP\");\n  }\n\n  /**\n   * Handles calls to {@link Player#release}.\n   *","sourceCodeStart":2922,"sourceCodeEnd":2958,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java#L2922-L2958","documentation":"Default handler for Player.prepare() in SimpleBasePlayer: it throws IllegalStateException because the subclass did not override handlePrepare(), while the current State advertises COMMAND_PREPARE. SimpleBasePlayer intentionally fails fast on unimplemented command handlers rather than silently no-op'ing.","triggerScenarios":"Calling player.prepare() on a SimpleBasePlayer subclass whose State includes COMMAND_PREPARE in availableCommands but which does not override handlePrepare().","commonSituations":"Custom player implementations (e.g. casting to a third-party backend) that keep the default full command set; migrating an implementation onto SimpleBasePlayer and missing one handler.","solutions":["Override handlePrepare() to trigger your backend's prepare and return a future completed when the state update lands.","Or exclude COMMAND_PREPARE from the State's available commands if preparation is not a meaningful operation for your player.","Add a test asserting each advertised command either has an override or is excluded."],"exampleFix":"// before\n// subclass relies on default commands, no handlePrepare\n\n// after\n@Override\nprotected ListenableFuture<?> handlePrepare() {\n  backend.prepare();\n  return updateStateAndNotify(state.buildUpon().setPlaybackState(STATE_BUFFERING).build());\n}","handlingStrategy":"validation","validationCode":"// In your State construction:\nif (!supportsPrepare) commands.remove(Player.COMMAND_PREPARE);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Implement handlePrepare() or exclude COMMAND_PREPARE.","Cover every advertised command with an integration test that calls it.","Treat IllegalStateException from SimpleBasePlayer handlers as an implementation bug, never catch-and-ignore in production."],"tags":["simplebaseplayer","custom-player","prepare","media3","contract"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}