{"record":{"id":"1650e14aee04d766","repo":"grpc/grpc-java","slug":"channel-state-api-is-not-implemented","errorCode":null,"errorMessage":"Channel state API is not implemented","messagePattern":"Channel state API is not implemented","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/grpc/internal/ConnectivityStateManager.java","lineNumber":85,"sourceCode":"        return;\n      }\n      // Swap out callback list before calling them, because a callback may register new callbacks,\n      // if run in direct executor, can cause ConcurrentModificationException.\n      ArrayList<Listener> savedListeners = listeners;\n      listeners = new ArrayList<>();\n      for (Listener listener : savedListeners) {\n        listener.runInExecutor();\n      }\n    }\n  }\n\n  /**\n   * Gets the current connectivity state of the channel. This method is threadsafe.\n   */\n  ConnectivityState getState() {\n    ConnectivityState stateCopy = state;\n    if (stateCopy == null) {\n      throw new UnsupportedOperationException(\"Channel state API is not implemented\");\n    }\n    return stateCopy;\n  }\n\n  private static final class Listener {\n    final Runnable callback;\n    final Executor executor;\n\n    Listener(Runnable callback, Executor executor) {\n      this.callback = callback;\n      this.executor = executor;\n    }\n\n    void runInExecutor() {\n      executor.execute(callback);\n    }\n  }\n}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/core/src/main/java/io/grpc/internal/ConnectivityStateManager.java#L67-L103","documentation":"ConnectivityStateManager.getState() returns the channel's connectivity state, but the manager starts with no state set and only learns states once a transport reports them. Calling getState() on a channel whose transport never installed a state manager throws UnsupportedOperationException, indicating the channel's state API is not wired up.","triggerScenarios":"Calling Channel.getState(false/true) on a channel implementation (typically a test transport or Channel/shim without state reporting) that never calls gotoState(), so the internal `state` field is still null.","commonSituations":"Using in-process or custom test transports that don't implement the state API; calling getState() before any connection attempt on a transport lacking state reporting; building a custom transport that forgot to propagate connectivity states.","solutions":["Use a real transport (e.g. NettyChannelBuilder) that reports connectivity states instead of a test/minimal transport.","Guard calls to Channel.getState() with a check of whether the transport supports the state API, or catch UnsupportedOperationException.","If implementing a transport, ensure the LoadBalancer/transport calls the connectivity-state callbacks so the manager is initialized."],"exampleFix":"// before\nConnectivityState state = channel.getState(false);\n// after\nConnectivityState state;\ntry {\n  state = channel.getState(false);\n} catch (UnsupportedOperationException e) {\n  state = ConnectivityState.IDLE; // transport does not expose state\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  state = channel.getState(false);\n} catch (UnsupportedOperationException e) {\n  state = null; // transport doesn't support state API\n}","preventionTips":["Use transports known to report connectivity states (e.g. Netty).","Avoid calling getState() on test/minimal transports.","When implementing a transport, wire up the state manager callbacks."],"tags":["grpc","connectivity-state","unsupported-operation","channel"],"backgroundTag":"method-not-implemented","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}