{"record":{"id":"c25542eeab9f2f9e","repo":"microg/GmsCore","slug":"callable-must-not-be-null","errorCode":null,"errorMessage":"Callable must not be null","messagePattern":"Callable must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java","lineNumber":116,"sourceCode":"     */\n    @Deprecated\n    public static <TResult> Task<TResult> call(Callable<TResult> callable) {\n        return call(TaskExecutors.MAIN_THREAD, callable);\n    }\n\n    /**\n     * Returns a {@link Task} that will be completed with the result of the specified {@code Callable}.\n     * <p/>\n     * If a non-{@link Exception} throwable is thrown in the callable, the {@link Task} will be failed with a\n     * {@link RuntimeException} whose cause is the original throwable.\n     *\n     * @param executor the Executor to use to call the {@code Callable}\n     * @deprecated Use {@link TaskCompletionSource} instead, which allows the caller to manage their own Executor.\n     */\n    @Deprecated\n    public static <TResult> Task<TResult> call(Executor executor, Callable<TResult> callable) {\n        if (executor == null) throw new IllegalArgumentException(\"Executor must not be null\");\n        if (callable == null) throw new IllegalArgumentException(\"Callable must not be null\");\n        TaskCompletionSource<TResult> taskCompletionSource = new TaskCompletionSource<>();\n        executor.execute(() -> {\n            try {\n                taskCompletionSource.setResult(callable.call());\n            } catch (Exception e) {\n                taskCompletionSource.trySetException(e);\n            } catch (Throwable t) {\n                taskCompletionSource.trySetException(new RuntimeException(t));\n            }\n        });\n        return taskCompletionSource.getTask();\n    }\n\n    /**\n     * Returns a canceled Task.\n     */\n    public static <TResult> Task<TResult> forCancelled() {\n        TaskImpl<TResult> task = new TaskImpl<>();","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-tasks/src/main/java/com/google/android/gms/tasks/Tasks.java#L98-L134","documentation":"The deprecated Tasks.call(Executor, Callable) requires a non-null Callable whose body produces the task result. A null Callable has nothing to run on the executor, so the method throws this IllegalArgumentException immediately.","triggerScenarios":"Calling Tasks.call(executor, null), often from a generic helper that forwards a supplier/callable which is null (uninitialized lambda field, optional computation skipped), or reflective/dynamic code that failed to build the Callable.","commonSituations":"Kotlin/Java interop where a Kotlin lambda coerced to Callable? arrives as null; helper methods like runIfConfigured(executor, maybeCallable) invoked when the computation is absent; refactors that removed the work but left the call site.","solutions":["Pass a real Callable implementation/lambda; if the work is optional, guard the call site instead of passing null","Return an already-completed Task via Tasks.forResult(defaultValue) when there is no work to run","Migrate to TaskCompletionSource (per deprecation notice) and only start work when the callable exists"],"exampleFix":"// before\nTask<Integer> task = Tasks.call(executor, getCallable()); // getCallable() may return null\n// after\nCallable<Integer> c = getCallable();\nTask<Integer> task = (c != null)\n    ? Tasks.call(executor, c)\n    : Tasks.forResult(0); // or skip the call entirely","handlingStrategy":"validation","validationCode":"if (callable == null) {\n    return Tasks.forResult(defaultValue); // nothing to run\n}","typeGuard":"static <T> boolean hasWork(Callable<T> c) {\n    return c != null;\n}","tryCatchPattern":"try {\n    Task<T> t = Tasks.call(executor, callable);\n} catch (IllegalArgumentException e) {\n    // skip or provide default result\n    Task<T> t = Tasks.forResult(null);\n}","preventionTips":["Guard optional computations at the call site instead of passing null Callables","Return completed tasks (Tasks.forResult) when there is no work","Migrate to TaskCompletionSource to make 'start work' explicit and null-impossible"],"tags":["android","null-check","callable","deprecated-api"],"backgroundTag":"null-argument","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}