Unnecessary record parameter in method call

Properties
LC0096 Warning Usage Code Fix Ignore Obsolete

When a method is invoked on a record variable with dot-notation, the method already operates on that record through the implicit Rec variable. Passing the same variable back as an argument does nothing — both the caller and the callee are looking at the same record instance. The extra parameter obscures the real parameter list and can mislead a future reader into thinking the method needs an external record when it does not.

The same applies inside a table, page, or extension that calls a sibling method and passes Rec explicitly: the callee already has access to Rec, so the argument is redundant.

Remove the redundant parameter from the call site and the corresponding parameter definition from the method signature.

Example: external call

The following code passes Customer to a method that is already invoked on Customer:

codeunit 50100 MyCodeunit
{
    procedure MyProcedure()
    var
        Customer: Record Customer;
    begin
        Customer.DoSomething(Customer); // Unnecessary record parameter in method call [LC0096]
    end;
}

Remove the redundant parameter and update the method signature:

codeunit 50100 MyCodeunit
{
    procedure MyProcedure()
    var
        Customer: Record Customer;
    begin
        Customer.DoSomething();
    end;
}

Example: internal call

Inside a table, passing Rec to a sibling method is equally redundant:

table 50100 MyTable
{
    fields
    {
        field(1; Name; Text[100]) { }
    }

    procedure Validate()
    begin
        DoSomething(Rec); // Unnecessary record parameter in method call [LC0096]
    end;

    procedure DoSomething(var MyTable: Record MyTable)
    begin
    end;
}

To fix this, remove the parameter:

table 50100 MyTable
{
    fields
    {
        field(1; Name; Text[100]) { }
    }

    procedure Validate()
    begin
        DoSomething();
    end;

    procedure DoSomething()
    begin
    end;
}

Exception

The rule suppresses the diagnostic in several cases where the parameter is intentional:

  • Event publishers: passing Rec to an event is idiomatic AL — subscribers need the record context.
  • Public or internal page methods: on a page or page extension, only local methods are flagged. Public and internal methods that accept the source record are considered intentional API design for decoupling and testability.
  • Different module: when the target method is defined in a different module, the developer cannot refactor the external signature.
  • Built-in methods: calls to built-in methods (Clear, Page.RunModal, etc.) are excluded.
  • Different variable or field access: Customer.DoSomething(Customer2) or Customer.DoSomething(Customer."No.") are not flagged because the argument is not the same record instance.

Edge case: local method called with multiple record instances

A local procedure that takes a record parameter may be called with several different record instances — some of them Rec. The diagnostic still fires on the Rec call. The usual fix — invoke the method on the record instead (Other.DoSomething()) — does not apply here: it would force the local procedure to become public or internal for no reason other than satisfying the rule.

table 50100 MyTable
{
    fields
    {
        field(1; Name; Text[100]) { }
    }

    procedure Validate()
    var
        Other: Record MyTable;
    begin
        DoSomething(Other);
        DoSomething(Rec); // Unnecessary record parameter in method call [LC0096]
    end;

    local procedure DoSomething(MyTable: Record MyTable)
    begin
    end;
}

Add a parameterless overload that assigns Rec to a local variable and delegates to the parameterized procedure. The delegating call passes a local variable, not Rec, so the diagnostic no longer fires — and the call site no longer implicitly passes the same record twice. The cost is one extra local variable and a record copy.

table 50100 MyTable
{
    fields
    {
        field(1; Name; Text[100]) { }
    }

    procedure Validate()
    var
        Other: Record MyTable;
    begin
        DoSomething(Other);
        DoSomething();
    end;

    local procedure DoSomething()
    var
        MyTable: Record MyTable;
    begin
        MyTable := Rec;
        DoSomething(MyTable);
    end;

    local procedure DoSomething(MyTable: Record MyTable)
    begin
    end;
}