Unnecessary record parameter in method call
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
Recto an event is idiomatic AL — subscribers need the record context. - Public or internal page methods: on a page or page extension, only
localmethods 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)orCustomer.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;
}