@future method takes an sObject or a collection of sObjects

ID

apex.correctness.future_methods_accept_sobjects

Severity

high

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Api Design

Language

Apex

Description

Reports a @future method whose parameter list contains an sObject, a custom object, or a collection of them. @future accepts only primitives and collections of primitives.

Rationale

The platform rejects the signature, so the class fails to compile or deploy - and if the type is generic enough to slip through, the object would in any case be serialized at enqueue time and arrive stale: by the time the job runs, the record in the database may have changed, and the copy the method holds would overwrite it. Passing ids instead makes the freshness explicit, because the method has to query for the current row.

The following code illustrates the pattern detected by this rule:

public class AsyncSignatures {

    // FLAGGED: @future method takes an sObject or a collection of sObjects
    @future
    public static void syncAccounts(List<Account> accts) {
        System.debug(accts);
    }

    // FLAGGED: @future method takes an sObject or a collection of sObjects
    @future(callout=true)
    public static void pushOrder(Order__c order) {
        System.debug(order);
    }

    @future
    public static void syncAccountIds(Set<Id> accountIds) {
        List<Account> accts = [SELECT Id, Name FROM Account];
        System.debug(accts);
    }

    @future(callout=true)
    public static void pushPayload(String payload) {
        System.debug(payload);
    }
}

Remediation

Pass Set<Id> or List<Id> and re-query the records inside the method, which also gives the asynchronous work the current field values. Where a whole payload has to travel, serialize it to a String with JSON.serialize - or use a Queueable, which takes typed member state including sObjects.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved