{"record":{"id":"afcc445f48d80db2","repo":"Netflix/Hystrix","slug":"command-should-implement-interface-to-execute-i","errorCode":null,"errorMessage":"Command should implement {} interface to execute in: {} mode","messagePattern":"Command should implement (.+?) interface to execute in: (.+?) mode","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/CommandExecutor.java","lineNumber":75,"sourceCode":"                        && ExecutionType.ASYNCHRONOUS == metaHolder.getFallbackExecutionType()) {\n                    return new FutureDecorator(executable.queue());\n                }\n                return executable.queue();\n            }\n            case OBSERVABLE: {\n                HystrixObservable observable = castToObservable(invokable);\n                return ObservableExecutionMode.EAGER == metaHolder.getObservableExecutionMode() ? observable.observe() : observable.toObservable();\n            }\n            default:\n                throw new RuntimeException(\"unsupported execution type: \" + executionType);\n        }\n    }\n\n    private static HystrixExecutable castToExecutable(HystrixInvokable invokable, ExecutionType executionType) {\n        if (invokable instanceof HystrixExecutable) {\n            return (HystrixExecutable) invokable;\n        }\n        throw new RuntimeException(\"Command should implement \" + HystrixExecutable.class.getCanonicalName() + \" interface to execute in: \" + executionType + \" mode\");\n    }\n\n    private static HystrixObservable castToObservable(HystrixInvokable invokable) {\n        if (invokable instanceof HystrixObservable) {\n            return (HystrixObservable) invokable;\n        }\n        throw new RuntimeException(\"Command should implement \" + HystrixObservable.class.getCanonicalName() + \" interface to execute in observable mode\");\n    }\n\n}\n","sourceCodeStart":57,"sourceCodeEnd":86,"githubUrl":"https://github.com/Netflix/Hystrix/blob/5ce3bc58c38e7ca60ef2fe0e516e390e294ad941/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/CommandExecutor.java#L57-L86","documentation":"When a command must be executed via queue()/execute() (SYNCHRONOUS or ASYNCHRONOUS execution types), the created HystrixInvokable must implement HystrixExecutable. Javanica throws this RuntimeException when the invokable built for the method is a HystrixObservableCommand-based object (which only implements HystrixObservable) but the derived execution type demands queue semantics — an execution-type/invokable-kind mismatch.","triggerScenarios":"A command meta-holder built for observable-style execution (e.g. GenericObservableCommand wrapping a Single/Completable/observe-mode action) but dispatched with ExecutionType.SYNCHRONOUS or ASYNCHRONOUS — typically from a collapser whose batch command returns rx types while the collapser method returns plain/Future types, or custom factories pairing the wrong invokable with the wrong execution type.","commonSituations":"Mixing rx return types (Single/Completable) on batch methods with non-Observable collapser signatures; custom HystrixCommandFactory extensions; version-skewed classpaths producing inconsistent factory selection.","solutions":["Make return types consistent: if the underlying action returns rx Observable/Single/Completable, declare the annotated method (or collapser chain) with Observable-compatible execution, e.g. return Observable<T>.","If the method should be sync/async, make the action return a plain value (or use toBlocking().single() style bridging inside the action) so a GenericCommand is built.","Audit custom HystrixCommandFactory/MetaHolderFactory overrides to confirm the invokable kind matches the execution type."],"exampleFix":"// before\n@HystrixCommand\npublic Single<User> getUser(String id) { ... }   // observable invokable\n... userService.getUser(id).toBlocking().value(); // invoked via async path mismatch\n\n// after\n@HystrixCommand\npublic User getUser(String id) { return loadUser(id); }  // sync execution\n// or declare: public Observable<User> getUser(String id)","handlingStrategy":"validation","validationCode":"static boolean rxTypesConsistentWithExecution(Method m) {\n    Class<?> rt = m.getReturnType();\n    boolean rx = rx.Observable.class.isAssignableFrom(rt) || rx.Single.class.isAssignableFrom(rt) || rx.Completable.class.isAssignableFrom(rt);\n    boolean syncAsync = !rx;\n    // sync/async methods must return plain types or Future; rx types must be served via Observable execution\n    return true; // enforce in code review: rx types only with observable-style declarations\n}","typeGuard":null,"tryCatchPattern":"try { ... } catch (RuntimeException e) when 'Command should implement' in message → fail fast and log invokable class + executionType; this is a wiring/version mismatch, not transient.","preventionTips":["Keep annotated-method return types (plain/Future vs rx.Observable/Single/Completable) consistent with the execution model the command is built for.","Align hystrix artifact versions; smoke-test every distinct return-type shape in CI."],"tags":["hystrix","javanica","execution-type","observable","internal"],"backgroundTag":null,"analyzedSha":"5ce3bc58c38e7ca60ef2fe0e516e390e294ad941","analyzedAt":"2026-08-14T10:55:35.600Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}