{"record":{"id":"9fc3be0cac7a2732","repo":"apache/pulsar","slug":"javainstancerunnable-is-not-initialized","errorCode":null,"errorMessage":"javaInstanceRunnable is not initialized","messagePattern":"javaInstanceRunnable is not initialized","errorType":"exception","errorClass":"PulsarServerException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/runtime/thread/ThreadRuntime.java","lineNumber":311,"sourceCode":"        statsFuture.complete(functionStatus);\n        return statsFuture;\n    }\n\n    @Override\n    public CompletableFuture<MetricsData> getAndResetMetrics() {\n        return CompletableFuture.completedFuture(javaInstanceRunnable.getAndResetMetrics());\n    }\n\n\n    @Override\n    public CompletableFuture<MetricsData> getMetrics(int instanceId) {\n        return CompletableFuture.completedFuture(javaInstanceRunnable.getMetrics());\n    }\n\n    @Override\n    public String getPrometheusMetrics() throws IOException {\n        if (javaInstanceRunnable == null) {\n            throw new PulsarServerException(\"javaInstanceRunnable is not initialized\");\n        }\n        return javaInstanceRunnable.getStatsAsString();\n    }\n\n    @Override\n    public CompletableFuture<Void> resetMetrics() {\n        javaInstanceRunnable.resetMetrics();\n        return CompletableFuture.completedFuture(null);\n    }\n\n    @Override\n    public boolean isAlive() {\n        if (this.fnThread != null) {\n            return this.fnThread.isAlive();\n        } else {\n            return false;\n        }\n    }","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/runtime/thread/ThreadRuntime.java#L293-L329","documentation":"ThreadRuntime.getPrometheusMetrics() returns the Java instance's stats as a Prometheus string, but this only works after the instance runnable has been created/started. If javaInstanceRunnable is still null (getPrometheusMetrics called before the thread instance finished initializing), it throws PulsarServerException('javaInstanceRunnable is not initialized').","triggerScenarios":"Calling getPrometheusMetrics() (e.g. via the worker's metrics/promise endpoint) on a ThreadRuntime whose start() has not yet constructed javaInstanceRunnable, or after initialization failed before runnable creation.","commonSituations":"Metrics scrapers hitting the function worker immediately after function assignment, racing instance startup; function instance failed to initialize leaving the runtime half-constructed; tests or tooling invoking getPrometheusMetrics() on a freshly created ThreadRuntime.","solutions":["Ensure the function instance has fully started before scraping its Prometheus metrics (retry the metrics call after startup completes).","Investigate why initialization never created javaInstanceRunnable (check earlier instance startup errors in the worker log).","Handle PulsarServerException from the metrics endpoint and treat it as retryable/until-ready.","In code, guard calls so getPrometheusMetrics is only invoked on a started ThreadRuntime."],"exampleFix":"// before\nString metrics = threadRuntime.getPrometheusMetrics();\n// after\ntry {\n    String metrics = threadRuntime.getPrometheusMetrics();\n} catch (PulsarServerException e) {\n    // instance not started yet; retry after startup or skip this scrape\n}","handlingStrategy":"try-catch","validationCode":"// only call after the instance has started; expose/check a started flag if you own the lifecycle\nif (!instanceStarted) {\n    throw new IllegalStateException(\"call getPrometheusMetrics only after ThreadRuntime.start() completed\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String metrics = threadRuntime.getPrometheusMetrics();\n} catch (PulsarServerException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"javaInstanceRunnable is not initialized\")) {\n        // instance not started yet: retry after startup or skip this scrape\n    } else {\n        throw e;\n    }\n}","preventionTips":["Delay metrics scraping until the function instance reports started/running.","Monitor instance startup failures — a null runnable means initialization never completed.","Make metrics scrapers tolerant of a 'not ready' window after function assignment."],"tags":["pulsar-functions","metrics","lifecycle","thread-runtime"],"backgroundTag":"not-yet-initialized","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}