If you’re tinkering with SharePoint Online using PowerShell and the Set-PnPListItem
cmdlet, only to randomly hit an error like “Error: The file A has been modified by A on A.”, it can feel like your script’s playing hide-and-seek with you! One minute it works fine, the next it’s throwing this cryptic message. This issue popped up on Stack Overflow on February 11, 2025, tied to a script updating SharePoint document library metadata from an Excel file. Don’t stress—I’m here to break down why this happens, what it means, and how to fix the Set-PnPListItem file modified error in SharePoint step-by-step. Think of me as your coding sidekick, guiding you through the mess so your script runs smooth as butter. Let’s dive in!
What’s This “File Has Been Modified” Error?
Imagine you’re editing a shared Google Doc with a friend. You both save at the same time, and—bam!—it yells about a conflict. That’s kinda what’s happening here. When you run Set-PnPListItem
to update a file’s metadata (like Title or Modified By) in a SharePoint document library, you might see:
Error: The file XXXX has been modified by XXXXX on XXXXX.
This isn’t a PowerShell bug—it’s SharePoint saying, “Hold up, someone (or something) touched this file since you last checked it, and I’m not sure what to do!” It’s a version conflict, and it’s random because it depends on timing, other users, or even SharePoint itself.
Why It Happens
This error hit a user on Stack Overflow (February 11, 2025) with a script that:
- Reads an Excel file.
- Checks if a file exists in SharePoint with
Get-PnPFile
. - Updates it with
Set-PnPListItem
if it’s there.
The catch? It worked all morning, then started flaking out. Here’s why:
- Concurrency: Another user, process (like a workflow), or even your script’s earlier actions modified the file between
Get-PnPFile
andSet-PnPListItem
. - SharePoint Sync: Tools like OneDrive or Office updates might tweak the file mid-script.
- Workflows: If your library has a flow or workflow (e.g., approval), it could update the file’s metadata—like “Modified By”—right when you’re trying to.
- Caching: SharePoint’s internal state might not sync fast enough, causing a mismatch.
Let’s squash this error and get your script humming again!
Step 1: Understand the Script Flow
First, let’s peek at what your script might look like (inspired by the Stack Overflow case):
$excelData = Import-Csv "C:\data.csv"
Connect-PnPOnline -Url "https://yourtenant.sharepoint.com/sites/yoursite" -Interactive
foreach ($row in $excelData) {
$fileName = $row.FileName
$filePath = "/Documents/$fileName"
# Check if file exists
$file = Get-PnPFile -Url $filePath -ErrorAction SilentlyContinue
if ($file) {
$listItem = Get-PnPListItem -List "Documents" -Id $file.ListItemId
Set-PnPListItem -List "Documents" -Identity $listItem.Id -Values @{"Title" = $row.Title}
} else {
Write-Host "File $fileName not found!"
}
}
- Flow: It grabs Excel data, checks for a file, and updates its metadata.
- Error Spot: Between
Get-PnPFile
andSet-PnPListItem
, something changes the file.
Strategy 1: Lock It Down with Retry Logic
Since the error’s random, let’s retry the update if SharePoint complains—like giving it a second chance to behave.
How to Do It
Wrap Set-PnPListItem
in a retry loop:
function Update-WithRetry {
param ($List, $Identity, $Values, $MaxRetries = 3)
$attempt = 0
$success = $false
while (-not $success -and $attempt -lt $MaxRetries) {
try {
Set-PnPListItem -List $List -Identity $Identity -Values $Values -ErrorAction Stop
$success = $true
} catch {
if ($_.Exception.Message -match "has been modified") {
$attempt++
Write-Host "Retry $attempt for $Identity due to modification conflict..."
Start-Sleep -Seconds 2 # Wait a bit
$file = Get-PnPFile -Url $filePath # Refresh file state
$Identity = $file.ListItemId
} else {
throw $_ # Other errors, stop trying
}
}
}
if (-not $success) { Write-Host "Failed after $MaxRetries tries!" }
}
# Updated script
foreach ($row in $excelData) {
$fileName = $row.FileName
$filePath = "/Documents/$fileName"
$file = Get-PnPFile -Url $filePath -ErrorAction SilentlyContinue
if ($file) {
Update-WithRetry -List "Documents" -Identity $file.ListItemId -Values @{"Title" = $row.Title}
}
}
- Retry: Tries up to 3 times if the “modified” error hits.
- Refresh: Grabs the latest file state before retrying.
Why It Works
It gives SharePoint a moment to settle—like waiting for your friend to finish editing that Google Doc. Stack Overflow users (February 11, 2025) praised retry loops for flaky SharePoint updates.
Strategy 2: Pause Sync Tools
If you’re using OneDrive or another sync tool, it might be ninja-editing files mid-script.
How to Do It
- Pause OneDrive: Right-click the OneDrive icon in your taskbar > Pause Syncing > pick 2 hours (or until your script’s done).
- Check Office Updates: Wait out any Microsoft Office auto-updates (they can tweak files too).
Test It
Run your script with sync paused. No errors? Sync was the sneaky culprit!
Why It Works
Sync tools like OneDrive can update file metadata (e.g., “Modified” timestamp) behind the scenes, tripping up Set-PnPListItem
. Pausing them keeps the file stable (per Microsoft Q&A, February 17, 2025).
Strategy 3: Check for Workflows or Flows
Got a workflow or Power Automate flow on your library? It might be racing your script to update the file.
How to Check
- Go to your SharePoint site > Library Settings > Workflow Settings or Power Automate tab.
- Look for flows like “Update Status” or “Approval” that change metadata.
Fix It
- Disable Temporarily: Turn off the flow in Power Automate (toggle to “Off”) while running your script.
- Adjust Flow: If it’s auto-updating “Modified By,” tweak it to skip files your script touches (e.g., add a condition like “Title not equals ScriptRun”).
Why It Works
A SharePoint Diary post (March 15, 2023) notes workflows often cause this error by updating files mid-operation—like two chefs fighting over the same pot. Pausing them clears the kitchen.
Strategy 4: Use -SystemUpdate for Silent Updates
If you don’t need versioning or “Modified By” changes, -SystemUpdate
can dodge the conflict.
How to Do It
Modify your Set-PnPListItem
call:
foreach ($row in $excelData) {
$fileName = $row.FileName
$filePath = "/Documents/$fileName"
$file = Get-PnPFile -Url $filePath -ErrorAction SilentlyContinue
if ($file) {
Set-PnPListItem -List "Documents" -Identity $file.ListItemId -Values @{"Title" = $row.Title} -SystemUpdate
}
}
-SystemUpdate
: Updates without changing “Modified” or creating a new version.
Why It Works
It’s like sneaking in a ninja update—SharePoint doesn’t log it as a user edit, reducing conflict chances (PnP PowerShell docs, GitHub #2016). Note: It might not set “Author” or “Editor”—use regular update for those.
Strategy 5: Refresh Before Updating
Grab the latest file state right before the update to sync with SharePoint’s reality.
How to Do It
foreach ($row in $excelData) {
$fileName = $row.FileName
$filePath = "/Documents/$fileName"
$file = Get-PnPFile -Url $filePath -ErrorAction SilentlyContinue
if ($file) {
# Refresh right before update
$listItem = Get-PnPListItem -List "Documents" -Id $file.ListItemId
Set-PnPListItem -List "Documents" -Identity $listItem.Id -Values @{"Title" = $row.Title}
}
}
- Refresh:
Get-PnPListItem
pulls the latest version just beforeSet-PnPListItem
.
Why It Works
It’s like double-checking your Doc before saving—ensures you’re working with the current state (Stack Overflow, February 11, 2025).
Why This Error Is Random
SharePoint’s a busy place:
- Real-Time Edits: Users or flows might edit files mid-script.
- Server Lag: SharePoint’s cloud sync can lag, making timing unpredictable.
- Triggers: Workflows might kick in unexpectedly (e.g., after
Get-PnPFile
).
That’s why it worked all morning then flaked out—pure timing chaos!
Prevent It Next Time
- Test Small: Run on one file first—spot issues early.
- Log Changes: Add
Write-Host
to track what’s updating when. - Schedule Off-Peak: Run scripts when users or sync tools are quiet.
Wrapping Up: You’ve Tamed the Beast!
The “Error: The file A has been modified by A on A.” with Set-PnPListItem
is a sneaky SharePoint gremlin, but you’ve got the tools to fix it. Retry with grace, pause sync chaos, tame workflows, sneak updates with -SystemUpdate
, or refresh your state—you’ll banish this error for good. Your script’s back in charge, updating SharePoint like a pro. So, tweak that PowerShell, hit “Run,” and watch your metadata magic happen—error-free!