Incompatible field types across TransferFields

Properties
PC0020 Warning Design Code Fix Ignore Obsolete

TransferFields copies field values between records by matching field IDs, not field names. When two tables share a field ID but define incompatible data types, the call throws a runtime error at execution time.

The fields must have the same data type for the copying to succeed (text and code are convertible, other types are not). There must be room for the actual length of the contents of the field to be copied in the field to which it is to be copied. If any one of these conditions aren’t fulfilled, a runtime error will occur.

Record.TransferFields(var Record [, Boolean]) Method on Microsoft Learn

The compiler cannot catch this — the mismatch only surfaces when TransferFields executes. This rule performs a compile-time analysis of table schemas to detect incompatible field types before they reach production.

Example

Both tables define field ID 2, but "Sales Document" declares it as Decimal while "Posted Sales Document" declares it as Integer:

table 50100 "Sales Document"
{
    fields
    {
        field(1; "No."; Code[20]) { }
        field(2; Amount; Decimal) { }
    }
}

table 50101 "Posted Sales Document"
{
    fields
    {
        field(1; "No."; Code[20]) { }
        field(2; Amount; Integer) { }
    }

    procedure Post(SalesDoc: Record "Sales Document")
    begin
        Rec.TransferFields(SalesDoc); // Incompatible field types across TransferFields [PC0020]
    end;
}

Align the field types so they match across both tables:

table 50100 "Sales Document"
{
    fields
    {
        field(1; "No."; Code[20]) { }
        field(2; Amount; Decimal) { }
    }
}

table 50101 "Posted Sales Document"
{
    fields
    {
        field(1; "No."; Code[20]) { }
        field(2; Amount; Decimal) { }
    }

    procedure Post(SalesDoc: Record "Sales Document")
    begin
        Rec.TransferFields(SalesDoc);
    end;
}

When the diagnostic is reported

  • Direct TransferFields invocations: the rule compares field types between the source and target tables for all shared field IDs.
  • Table extensions: the base application has many table pairs coupled via TransferFields (e.g., Customer and Contact, or Purchase Header and Purch. Inv. Header). When your table extensions add a field with the same ID to both sides of a known pair, the rule checks that the types match — even though your extension never calls TransferFields directly.

The following type conversions are considered safe and do not trigger the diagnostic:

Source typeTarget type
CodeText
IntegerBigInteger or Decimal
EnumInteger
Any length-based typeSame type with equal or greater length

Exception

The three-parameter overload TransferFields(FromRecord, InitPrimaryKeyFields, SkipFieldsNotMatchingType) (available from runtime 4.2) accepts a SkipFieldsNotMatchingType parameter. When set to true, the platform skips fields with incompatible types instead of throwing a runtime error. The diagnostic is not reported when this parameter is true.

Use a pragma on the field definition when the type mismatch is intentional and you have verified it is handled:

#pragma warning disable PC0020
field(2; Amount; Integer) { }
#pragma warning restore PC0020

See also