Asynchronous work declared with @future

ID

apex.maintainability.avoid_future

Severity

info

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Api Design

Language

Apex

Description

Reports a method annotated @future, the oldest of the asynchronous Apex mechanisms.

Rationale

A @future method is a dead end: it cannot be chained, it cannot be monitored, it returns no job id, it cannot take sObjects or any non-primitive argument, and it cannot be called from another asynchronous context. Every one of those limits turns into a workaround the first time the requirement grows - a static flag to prevent re-entry, a query to re-fetch the records the caller already had, a second method to do the part @future refused.

The following code illustrates the pattern detected by this rule:

public class AsyncWork {

    // FLAGGED: Asynchronous work declared with @future
    @future
    public static void syncNames(Set<Id> accountIds) {
        System.debug(accountIds);
    }

    // FLAGGED: Asynchronous work declared with @future
    @future(callout=true)
    public static void pushToService(String payload) {
        System.debug(payload);
    }

    public static void enqueue(Set<Id> accountIds) {
        System.enqueueJob(new SyncNamesJob(accountIds));
    }
}

Remediation

Implement the work as a Queueable instead: it takes typed member state including sObjects, returns a job id you can monitor, chains to the next job, and can attach a Finalizer for failure handling. Keep @future only where an existing published signature forces it.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved