{"record":{"id":"202929ff839353d8","repo":"google/ExoPlayer","slug":"missing-implementation-to-handle-command-stop","errorCode":null,"errorMessage":"Missing implementation to handle COMMAND_STOP","messagePattern":"Missing implementation to handle COMMAND_STOP","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java","lineNumber":2953,"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<?> 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   *\n   * <p>Will only be called if {@link Player#COMMAND_RELEASE} 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<?> handleRelease() {\n    throw new IllegalStateException(\"Missing implementation to handle COMMAND_RELEASE\");\n  }\n\n  /**\n   * Handles calls to {@link Player#setRepeatMode}.\n   *","sourceCodeStart":2935,"sourceCodeEnd":2971,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java#L2935-L2971","documentation":"Default handler for Player.stop() in SimpleBasePlayer throws when the subclass neither overrides handleStop() nor removes COMMAND_STOP from the advertised commands. SimpleBasePlayer requires every available command to have a concrete handler.","triggerScenarios":"player.stop() (or stop with reset) is invoked on a SimpleBasePlayer subclass whose availableCommands include COMMAND_STOP while handleStop() is not implemented.","commonSituations":"Custom players built on SimpleBasePlayer with default command availability; integration code that calls stop() during teardown hitting an unfinished implementation.","solutions":["Override handleStop(): transition state to STATE_IDLE and clear the playlist (or reflect your backend's stop), returning the state-update future.","If stop is unsupported, remove COMMAND_STOP from the State's availableCommands.","Wire the override to also release backend resources so subsequent release() is cheap."],"exampleFix":"// before\n// no handleStop override; player.stop() throws\n\n// after\n@Override\nprotected ListenableFuture<?> handleStop() {\n  backend.stop();\n  return updateStateAndNotify(\n      new State.Builder().setPlaybackState(STATE_IDLE).setPlaylist(Collections.emptyList()).build());\n}","handlingStrategy":"validation","validationCode":"if (!supportsStop) commands.remove(Player.COMMAND_STOP);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Implement handleStop() (transition to STATE_IDLE, clear playlist) or drop COMMAND_STOP.","Call stop() in your own tests so the missing-handler bug surfaces during development.","Keep teardown logic idempotent."],"tags":["simplebaseplayer","custom-player","stop","media3","contract"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}