{"record":{"id":"c61f1223dedea58f","repo":"Netflix/Hystrix","slug":"asyncresult-is-just-a-stub-and-cannot-be-used-as-c","errorCode":null,"errorMessage":"AsyncResult is just a stub and cannot be used as complete implementation of Future","messagePattern":"AsyncResult is just a stub and cannot be used as complete implementation of Future","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AsyncResult.java","lineNumber":34,"sourceCode":"package com.netflix.hystrix.contrib.javanica.command;\n\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Fake implementation of {@link Future}. Can be used for method signatures\n * which are declared with a Future return type for asynchronous execution.\n * Provides abstract {@link #invoke()} method to wrap some logic for an asynchronous call.\n *\n * @param <T> the type of result\n */\npublic abstract class AsyncResult<T> implements Future<T>, ClosureCommand<T> {\n\n    private static final String ERROR_MSG = \"AsyncResult is just a stub and cannot be used as complete implementation of Future\";\n\n    @Override\n    public boolean cancel(boolean mayInterruptIfRunning) throws UnsupportedOperationException {\n        throw new UnsupportedOperationException(ERROR_MSG);\n    }\n\n    @Override\n    public boolean isCancelled() throws UnsupportedOperationException {\n        throw new UnsupportedOperationException(ERROR_MSG);\n    }\n\n    @Override\n    public boolean isDone() throws UnsupportedOperationException {\n        throw new UnsupportedOperationException(ERROR_MSG);\n    }\n\n    @Override\n    public T get() throws UnsupportedOperationException {\n        throw new UnsupportedOperationException(ERROR_MSG);\n    }\n\n    @Override","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/Netflix/Hystrix/blob/5ce3bc58c38e7ca60ef2fe0e516e390e294ad941/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AsyncResult.java#L16-L52","documentation":"AsyncResult is an abstract stub meant only as a declaration vehicle for async Hystrix command methods: Javanica intercepts the method, invokes your invoke() implementation on a Hystrix thread, and manages the real Future itself. The Future interface methods are implemented to always throw UnsupportedOperationException so nobody treats the AsyncResult instance as a working Future. This error is cancel(boolean).","triggerScenarios":"Directly calling cancel() on an AsyncResult instance, e.g. new AsyncResult<String>(){...}.cancel(true), or handing the AsyncResult object to code that manages Futures (timeout watchdogs, ExecutorService machinery, CompletableFuture adapters).","commonSituations":"Developers unfamiliar with the pattern trying to use the returned AsyncResult as a real Future; passing the collapser/command method body's return object into generic async orchestration code; calling cancel to abort a timed-out call.","solutions":["Remove code that invokes cancel/cancel-related Future methods on AsyncResult; cancellation is not supported by this pattern.","If you need a cancellable Future, return a real Future from the command method (or use queue() on a programmatic HystrixCommand) instead of AsyncResult.","Keep AsyncResult instances confined to the annotated method's return; treat the object as opaque."],"exampleFix":"// before\nAsyncResult<String> ar = userService.getName(id); // if directly exposed\nar.cancel(true);\n\n// after\n// let Javanica manage the Future; to use it, consume the method's returned Future:\nFuture<String> f = userService.getName(id);  // proxy returns a real Future\nString name = f.get(2, TimeUnit.SECONDS);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isAsyncResultStub(Future<?> f) {\n    return f instanceof com.netflix.hystrix.contrib.javanica.command.AsyncResult;\n}","tryCatchPattern":"try { f.cancel(true); } catch (UnsupportedOperationException e) { if (f instanceof AsyncResult) { /* stub by design — skip */ } else throw e; }","preventionTips":["Treat AsyncResult as opaque: construct-and-return inside the annotated method, never call Future methods on it.","Exclude AsyncResult instances from generic Future-management utilities via instanceof guard.","Need cancellation? Return a real Future or use a programmatic HystrixCommand with queue()."],"tags":["hystrix","javanica","async-result","future","misuse"],"backgroundTag":null,"analyzedSha":"5ce3bc58c38e7ca60ef2fe0e516e390e294ad941","analyzedAt":"2026-08-14T10:55:35.600Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}