{"record":{"id":"106ece26b10b321a","repo":"apache/hadoop","slug":"name-for-this-operation-the-current-service-s","errorCode":null,"errorMessage":"${name}: for this operation, the current service state must be ${expectedState} instead of ${state}","messagePattern":"(.+?): for this operation, the current service state must be (.+?) instead of (.+?)","errorType":"exception","errorClass":"ServiceStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/service/ServiceStateModel.java","lineNumber":99,"sourceCode":"\n  /**\n   * Query that the state is in a specific state\n   * @param proposed proposed new state\n   * @return the state\n   */\n  public boolean isInState(Service.STATE proposed) {\n    return state.equals(proposed);\n  }\n\n  /**\n   * Verify that that a service is in a given state.\n   * @param expectedState the desired state\n   * @throws ServiceStateException if the service state is different from\n   * the desired state\n   */\n  public void ensureCurrentState(Service.STATE expectedState) {\n    if (state != expectedState) {\n      throw new ServiceStateException(name+ \": for this operation, the \" +\n                                      \"current service state must be \"\n                                      + expectedState\n                                      + \" instead of \" + state);\n    }\n  }\n\n  /**\n   * Enter a state -thread safe.\n   *\n   * @param proposed proposed new state\n   * @return the original state\n   * @throws ServiceStateException if the transition is not permitted\n   */\n  public synchronized Service.STATE enterState(Service.STATE proposed) {\n    checkStateTransition(name, state, proposed);\n    Service.STATE oldState = state;\n    //atomic write of the new state\n    state = proposed;","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/service/ServiceStateModel.java#L81-L117","documentation":"ServiceStateModel.ensureCurrentState(expected) is a hard state assertion used by Service operations that are only legal in one lifecycle state; if the model's current state differs it throws ServiceStateException \"<name>: for this operation, the current service state must be <expected> instead of <state>\". Unlike enterState it never attempts a transition - it is a precondition check, so hitting it means the call was made at the wrong point in the lifecycle.","triggerScenarios":"Invoking a state-guarded operation on a service in another state: reading post-mortem state after STOPPED on a still-RUNNING instance, direct ServiceStateModel.ensureCurrentState calls in custom services, or assertions in lifecycle callbacks invoked at unexpected times.","commonSituations":"Custom AbstractService subclasses calling ensureCurrentState in serviceStop/serviceInit without guarding; tests asserting on services whose async stop has not completed; composite services touching children mid-transition.","solutions":["Guard the call: check service.isInState(expected) (or ServiceStateException-safe APIs) before invoking the state-guarded operation.","Fix the ordering: complete the prior transition (e.g. stop()) before invoking stop-only operations.","In custom services, prefer enterState()/getFailureState-style APIs which tolerate legal transitions instead of asserting."],"exampleFix":"// before\nmodel.ensureCurrentState(Service.STATE.STOPPED);\n// after\nif (service.isInState(Service.STATE.STOPPED)) {\n  model.ensureCurrentState(Service.STATE.STOPPED);\n  // ... stop-only work\n}","handlingStrategy":"validation","validationCode":"// Narrow before state-guarded operations\nif (!service.isInState(Service.STATE.STOPPED)) {\n  throw new IllegalStateException(\"post-mortem read requires STOPPED, state=\"\n      + service.getServiceState());\n}\n// proceed; ensureCurrentState(STOPPED) will now pass","typeGuard":"boolean isStopped(Service s) {\n  return s != null && s.isInState(Service.STATE.STOPPED);\n}","tryCatchPattern":"try {\n  model.ensureCurrentState(expected);\n} catch (ServiceStateException e) {\n  // read e.getMessage() for actual vs expected state; re-order lifecycle and retry\n}","preventionTips":["Check isInState(expected) before every state-guarded operation.","Wait for asynchronous stop completion (waitForServiceToStop) before stop-only assertions.","Prefer AbstractService lifecycle callbacks over direct ServiceStateModel calls."],"tags":["service","lifecycle","state-machine","precondition"],"backgroundTag":"service-state-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}