Tutorials/Power Apps/Mastering Patch for SharePoint: A Complete Guide to Every Column Type in Power Apps
Power Appsintermediate

Mastering Patch for SharePoint: A Complete Guide to Every Column Type in Power Apps

Learn how to use the Patch function effectively across all standard SharePoint column types with a practical asset management scenario. Covers text, numbers, dates, people, choices, lookups, images, hyperlinks, currencies, and task outcomes.

NA
Narmer Abader
@narmer · Published June 3, 2026

The Patch function is the most precise tool in Power Fx for writing data back to SharePoint. Unlike SubmitForm, which handles an entire form, Patch lets you surgically update specific fields on specific records — or create entirely new items with exactly the fields you want. But every SharePoint column type expects a strict schema. Get the syntax wrong, and you face silent empty values, data loss errors, or confusing type-mismatch failures.

In this guide we’ll build a real-world app for managing Contoso’s IT equipment. You’ll learn the exact syntax for every major SharePoint column type, from simple text to multi-value people pickers and images.

Scenario Overview

Our SharePoint list is called ContosoEquipment. It holds IT assets for the company.

Field NameSharePoint TypeInternal Name
Asset NameSingle line of textTitle
DescriptionMultiple lines of textAssetDescription
Serial NumberNumberSerialNumber
ActiveYes / NoIsActive
Assigned ToPerson or Group (single)AssignedTo
Support TeamPerson or Group (multi)SupportTeam
Purchase DateDate onlyPurchaseDate
Last ServiceDate and TimeLastService
CategoryChoice (single)Category
TagsChoice (multi)Tags
Vendor NameLookupVendorName
PhotoImagePhoto
Vendor SiteHyperlinkVendorSite
CostCurrencyCost
Approval StatusTask OutcomeApprovalStatus

Our app will let a user create and update items from a gallery using one central Patch call.

Patch Syntax Reference

Every column type below is shown as a ChangeRecord that you can drop directly into Patch(DataSourceName, BaseRecord, { ... }).

Text & Numbers

Single-line, multi-line, number, and currency columns accept a simple string or number. Never wrap numbers in quotes.

powerfxText and Number Columns
{
  Title: "Surface Pro 9",
  AssetDescription: "Primary development machine with 16 GB RAM",
  SerialNumber: 128934,
  Cost: 1899.99
}

Dates & Boolean

Date-only fields ignore the time component of the value you pass. For Date & Time columns, the time is preserved. A Yes/No column expects a Boolean (true / false).

powerfxDates and Boolean Columns
{
  PurchaseDate: DatePicker1.SelectedDate,
  LastService: DateTimePicker1.SelectedDate,
  IsActive: Toggle1.Value
}

Choices

Single-choice columns require a record with a Value property. Multi-choice columns require an array of records, each with a Value property.

powerfxChoice Columns
// Single Choice
{ Category: { Value: "Laptop" } }

// Multi Choice
{ Tags: [{ Value: "Warranty" }, { Value: "Urgent" }] }

// To clear a multi-choice column
{ Tags: [] }

People / Person or Group

Person columns are the most complex because they require a specific set of Azure AD metadata. Always include the '@odata.type' property to distinguish between a user and a group. The Claims string must match your tenant exactly.

Claims Format

The Claims string follows the format i:0#.f|membership|user@domain.com for users and c:0o.c|federateddirectorygroup|groupId for groups. You can extract this from the User() function or from an existing 'Created By' field.

powerfxPeople Columns
// Single Person
{
  AssignedTo: {
      '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
      Claims: "i:0#.f|membership|user@contoso.com",
      DisplayName: "User Name",
      Email: "user@contoso.com"
  }
}

// Single Group
{
  AssignedTo: {
      '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedGroup",
      Claims: "c:0o.c|federateddirectorygroup|group-id",
      DisplayName: "Group Name",
      Email: "group@contoso.com"
  }
}

// Multi-Value People
{
  SupportTeam: [
      {
          '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
          Claims: "i:0#.f|membership|user1@contoso.com"
      },
      {
          '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
          Claims: "i:0#.f|membership|user2@contoso.com"
      }
  ]
}

A Lookup column stores a reference to another list item. You must supply both the display Value and the Id of the related item. A Hyperlink stores a URL and a description together as a record.

powerfxLookup and Hyperlink Columns
// Lookup (Value is the display name, Id is the item ID in the lookup list)
{ VendorName: { Value: "Contoso Supplies", Id: 1 } }

// Hyperlink
{ VendorSite: { Description: "Order Portal", Url: "https://contoso.com/orders" } }

Images

Uploading to an Image column requires the binary media from an Add Picture control. The LargeImage parameter expects the full blob, which you access via the .Media property. Smaller thumbnails use .Image, but for writing back to the column .Media is the reliable choice.

powerfxImage Column
{ Photo: { LargeImage: ImageUploader1.Media } }
Image Size Limits

The default file-size limit for list images is 10 MB. A 4K photo taken on a phone will often exceed this. Resize or compress the image before passing it to Patch to avoid silent failures.

Task Outcome

Task Outcome columns behave identically to a single-choice column. They are typically linked to SharePoint 2013 workflow tasks and use an underlying integer mapping, but Power Fx abstracts that away. You write to them exactly like a choice.

powerfxTask Outcome Column
{ ApprovalStatus: { Value: "Approved" } }
// Other valid values: "Not Started", "Pending", "Rejected", etc.

A Complete Create Example

Here is the full Patch call that creates a new asset with every column type populated at once.

powerfxComplete Item Create
Patch(
  ContosoEquipment,
  Defaults(ContosoEquipment),
  {
      Title: "Surface Pro 9",
      AssetDescription: "Primary dev machine",
      SerialNumber: 128934,
      IsActive: true,
      PurchaseDate: DatePicker1.SelectedDate,
      LastService: DateTimePicker1.SelectedDate,
      Category: { Value: "Laptop" },
      Tags: [{ Value: "Warranty" }],
      Cost: 1899.99,
      VendorName: { Value: "Contoso Ltd.", Id: 5 },
      AssignedTo: {
          '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
          Claims: "i:0#.f|membership|user@contoso.com",
          DisplayName: "User Name",
          Email: "user@contoso.com"
      },
      VendorSite: {
          Description: "Order Page",
          Url: "https://contoso.com/orders"
      },
      ApprovalStatus: { Value: "Pending" }
  }
)

Common Pitfalls

  • Mismatched Types — Passing a string to a Number or Currency column causes a type-mismatch error. Always convert text input to a number with Value(TextInput1.Text).
  • Choice Without Value — Writing { Category: "Laptop" } silently fails. You must use the { Value: "Laptop" } record syntax.
  • Missing @odata.type on People — Omitting the entity type can lead to the user not being saved correctly, especially when multiple users exist with the same display name.
  • Lookup Without Id — A Lookup column needs both Value and Id. The Value is used for display, but the link relies on the Id.
  • Hyperlink Property Order — The schema expects a record with Description and Url. Swapping them or providing a plain string will not work.
  • Image Column Upload — Using .Image instead of .Media for the write operation often leaves the column empty.
  • Unpatchable Types — Calculated, External Data, and Location columns cannot be written to via Patch. Always verify your list schema.

Recommendations

  • Use a Variable for Complex Records — Build the ChangeRecord as a collection or variable first. This makes debugging much easier because you can inspect the variable before the Patch executes.
    powerfxDebug with Variables
    Set(varRecord, { Title: "Dell Monitor", Cost: 450.00, ... });
    Patch(ContosoEquipment, Defaults(ContosoEquipment), varRecord);
  • Check for Errors — After a Patch, inspect the Errors() function or wrap the call in IfError() to capture failures gracefully.
  • Test in Isolation — When adding a new column type to an existing app, test the Patch for that single field before integrating it into a large record.

References