Skip to content

Get-PnPPage throws JSON deserialization error on valid CanvasContent1 (BytePositionInLine error) #5331

@elap58

Description

@elap58

Bug

Get-PnPPage fails with a System.Text.Json deserialization error when reading a modern site page whose stored CanvasContent1 is valid JSON. The error references a byte position into what appears to be PnP's internal intermediate document — not into the source CanvasContent1 field, which parses cleanly under strict JSON parsing.

The page renders correctly in the browser and can be opened/edited via the SharePoint UI. The underlying stored content is not corrupt. The error reproducibly occurs on both PnP.PowerShell 3.1.0 and 3.2.0.

Error message

Get-PnPPage: '' is invalid after a value. Expected either ',', '}', or ']'. Path: $ | LineNumber: 0 | BytePositionInLine: 4893.

Expected behavior

Get-PnPPage returns the page object for a page whose stored canvas content parses as valid JSON.

Actual behavior

The cmdlet throws the System.Text.Json error shown above. Same error signature reproduces on a separate page with different content at a different byte position — same content yields the same offset; different content yields a different offset. The behavior is deterministic.

Steps to reproduce

  1. Connect to a SharePoint site containing the affected page:
    Connect-PnPOnline -Url -ClientId -Interactive

  2. Attempt to read the page:
    Get-PnPPage -Identity "Events.aspx"

  3. Observe the System.Text.Json error.

Diagnostic evidence that the on-disk content is valid

The page's stored CanvasContent1 parses successfully under strict System.Text.Json parsing — every web-part data blob individually parses without error:

Add-Type -AssemblyName System.Text.Json
$item = Get-PnPListItem -List "Site Pages" |
    Where-Object { $_.FieldValues.FileRef -ilike "*/SitePages/Test.aspx" } |
    Select-Object -First 1
$canvas = $item.FieldValues.CanvasContent1
$blobs = [regex]::Matches($canvas, 'data-sp-webpartdata="([^"]+)"')
foreach ($b in $blobs) {
    $decoded = [System.Net.WebUtility]::HtmlDecode($b.Groups[1].Value)
    [System.Text.Json.JsonDocument]::Parse($decoded) | Out-Null   # all succeed
}

All web-part JSON blobs in the affected page parse successfully under System.Text.Json directly — the same strict parser that Get-PnPPage uses internally. Per-blob character inspection at the byte position reported by the error shows benign content (spaces, letters mid-string), confirming the reported byte position is into PnP's internal intermediate document, not into any single web part's stored JSON.

Suspected pattern

The affected pages contain custom web parts whose properties include JavaScript strings with regex literals using escaped forward slashes — e.g., replace(/\/$/, "") — and other backslash sequences embedded in string properties. These are properly escaped in the on-disk JSON (as \\ in the stored representation) and parse cleanly with strict JSON parsers. PnP's intermediate handling appears to mishandle backslash escaping somewhere during the round-trip between read and parse.

A minimal repro by web-part-level bisection has not been performed; happy to provide additional diagnostic output or a sanitized canvas dump if helpful.

Environment

  • PnP.PowerShell version: 3.1.0 and 3.2.0 (both affected)
  • PowerShell: 7.x
  • OS: Windows Server 2022 / Windows 11
  • Tenant type: SharePoint Online (commercial)
  • Auth methods reproduced under: certificate-based (unattended) and interactive (browser sign-in)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions