{"record":{"id":"d84d39f23cc2b00a","repo":"eclipse-vertx/vert.x","slug":"already-started","errorCode":null,"errorMessage":"Already started","messagePattern":"Already started","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/eventbus/impl/EventBusImpl.java","lineNumber":108,"sourceCode":"    return outboundInterceptors;\n  }\n\n  @Override\n  public EventBus clusterSerializableChecker(Function<String, Boolean> classNamePredicate) {\n    codecManager.clusterSerializableCheck(classNamePredicate);\n    return this;\n  }\n\n  @Override\n  public EventBus serializableChecker(Function<String, Boolean> classNamePredicate) {\n    codecManager.serializableCheck(classNamePredicate);\n    return this;\n  }\n\n  @Override\n  public synchronized void start(Promise<Void> promise) {\n    if (started) {\n      throw new IllegalStateException(\"Already started\");\n    }\n    started = true;\n    promise.complete();\n  }\n\n  @Override\n  public EventBus send(String address, Object message) {\n    return send(address, message, new DeliveryOptions());\n  }\n\n  @Override\n  public EventBus send(String address, Object message, DeliveryOptions options) {\n    MessageImpl msg = createMessage(true, isLocalOnly(options), address, options.getHeaders(), message, options.getCodecName());\n    sendOrPubInternal(msg, options, null);\n    return this;\n  }\n\n  @Override","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/eventbus/impl/EventBusImpl.java#L90-L126","documentation":"EventBusImpl.start(Promise) may only be called once per bus instance. If the 'started' flag is already true, it throws this IllegalStateException instead of silently starting twice, ensuring single initialization of reply-address infrastructure and metrics.","triggerScenarios":"Calling eventBus().start(promise) manually on an already-started bus, or Vert.xInternal start logic being invoked twice (e.g. from a custom Vertx bootstrap or restarting a closed Vertx instance).","commonSituations":"Application code that calls start() itself while the Vertx lifecycle already started the event bus; reusing a Vertx/EventBus instance after shutdown; embedding Vert.x in a framework that also calls start().","solutions":["Remove explicit eventBus().start() calls and let the Vertx instance start the bus during deployment.","Track whether start has been issued and skip a second call (idempotent bootstrap).","If the Vertx instance was closed, create a new Vertx rather than restarting the old one."],"exampleFix":"// before\nvertx.eventBus().start(promise); // second start on same bus\n// after\nif (!started.getAndSet(true)) {\n  vertx.eventBus().start(promise);\n}","handlingStrategy":"try-catch","validationCode":"// track start calls yourself\nprivate final AtomicBoolean busStarted = new AtomicBoolean();\nif (busStarted.compareAndSet(false, true)) {\n  bus.start(promise);\n}","typeGuard":null,"tryCatchPattern":"try {\n  bus.start(promise);\n} catch (IllegalStateException e) {\n  // already started; complete immediately\n  promise.complete();\n}","preventionTips":["Let the Vertx lifecycle start the event bus; avoid manual start() calls","Make bootstrap idempotent with AtomicBoolean.compareAndSet","Create a fresh Vertx instead of restarting a closed instance"],"tags":["eventbus","lifecycle","double-start","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}