Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Invoke-PnPSPRestMethod & Invoke-PnPGraphMethod - Pages API - Update - A possible object cycle was detected #2775

Closed
2 of 6 tasks
SjoerdV opened this issue Feb 1, 2023 · 6 comments · Fixed by #2802
Closed
2 of 6 tasks
Labels
bug Something isn't working

Comments

@SjoerdV
Copy link

SjoerdV commented Feb 1, 2023

Reporting an Issue

Using the Pages api through SharePoint REST API v2, this command:

Invoke-PnPSPRestMethod -Url "https://<tenant>.sharepoint.com/_api/v2.0/sites('<tenant>.sharepoint.com,00000000-0000-0000-0000-000000000000,00000000-0000-0000-0000-000000000000')/pages/00000000-0000-0000-0000-000000000000" -Method "PATCH" -Content $body -ContentType "application/json;charset=utf-8" -ErrorAction Stop

OR using the Graph directly:

Invoke-PnPGraphMethod -Url "beta/sites/<tenant>.sharepoint.com,00000000-0000-0000-0000-000000000000,00000000-0000-0000-0000-000000000000/pages/00000000-0000-0000-0000-000000000000" -Method "PATCH" -Content $body -ContentType "application/json" -ErrorAction Stop

(all guids replaced with empty guid)

returns:

A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 64. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.Members.Value.Members.Value.Members.Value.Members.Value.Members.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.Value.OverloadDefinitions.

Expected behavior

Update the Modern Page with the new configuration in $body

Actual behavior

Error message as depicted above.

NOTE1: I have verified that the object in the $body variable has a depth of 12 (no where near 64)
NOTE2: the $body variable contains a deeply nested representation of a SharePoint modern page, starting with these elements:

title        : FAQ
canvasLayout : @{horizontalSections=System.Object[]}

NOTE3: the exact same $body object variable passes without error through a direct Graph call using EasyGraph Module

What is the version of the Cmdlet module you are running?

1.12.0

Which operating system/environment are you running PnP PowerShell on?

  • Windows
  • Linux
  • MacOS
  • Azure Cloud Shell
  • Azure Functions
  • Other : please specify
@SjoerdV SjoerdV added the bug Something isn't working label Feb 1, 2023
@gautamdsheth
Copy link
Collaborator

Hey @SjoerdV , can you please paste the payload that you are sending ? Will try to fix this as well.

@SjoerdV
Copy link
Author

SjoerdV commented Feb 6, 2023

Sure, this is an JSON payload example (can be converted to PSObject with | ConvertFrom-Json -Depth 100)
(webId and siteId are replaced by empty guids)
To make the object a little more nested I used a PnP Search webpart in the configuration, but any simple 'canvasLayout' with only a few text webparts would deliver the same error message.

{
  "title": "FAQ",
  "canvasLayout": {
    "horizontalSections": [
      {
        "layout": "twoColumns",
        "id": "1",
        "emphasis": "none",
        "columns": [
          {
            "id": "1",
            "width": 6,
            "webparts": [
              {
                "id": "0493922d-ffff-4a7d-a42f-4bdb5f4ffff",
                "innerHtml": "<p>Testing text<br></p>"
              }
            ]
          },
          {
            "id": "2",
            "width": 6,
            "webparts": [
              {
                "id": "fda4496d-1590-ffff-a9a0-b026303cffff",
                "webPartType": "096b96cc-8a44-41fa-9b4d-c0ab2ab2a779",
                "data": {
                  "audiences": [],
                  "dataVersion": "1.0",
                  "description": "Allows users to enter query keywords",
                  "title": "Search Box",
                  "properties": {
                    "searchInNewPage": false,
                    "pageUrl": "",
                    "queryPathBehavior": 0,
                    "queryStringParameter": "q",
                    "openBehavior": 0,
                    "enableQuerySuggestions": false,
                    "useDynamicDataSource": false,
                    "NlpServiceUrl": "",
                    "enableNlpService": false,
                    "enableDebugMode": false,
                    "isStaging": true,
                    "placeholderText": "",
                    "suggestionProviders": [
                      {
                        "providerName": "default",
                        "providerDisplayName": "SharePoint Query Suggestions",
                        "providerDescription": "Default SharePoint query suggestions.",
                        "providerEnabled": true
                      }
                    ]
                  },
                  "serverProcessedContent": {
                    "htmlStrings": [],
                    "searchablePlainTexts": [],
                    "links": [],
                    "imageSources": []
                  }
                }
              },
              {
                "id": "8d1c710d-2d12-ffff-8fcb-891822c8ffff",
                "webPartType": "544c1372-42df-47c3-94d6-017428cd2baf",
                "data": {
                  "audiences": [],
                  "dataVersion": "1.0",
                  "description": "Displays JSON based data using customizable templates",
                  "title": "PnP - Search Results",
                  "properties": {
                    "documentationLink": "https://microsoft-search.github.io/pnp-modern-search/",
                    "selectedLayoutKey": "Cards",
                    "queryTextSource": 0,
                    "showSelectedFilters": false,
                    "showResultsCount": true,
                    "showBlankIfNoResult": false,
                    "useMicrosoftGraphToolkit": false,
                    "enableTelemetry": true,
                    "useVerticals": false,
                    "adaptiveCardsHostConfig": "{\n\t\"fontFamily\": \"Segoe UI, Helvetica Neue, sans-serif\"\n}",
                    "layoutRenderType": "Handlebars",
                    "resultTypes": [],
                    "selectedVerticalKeys": [],
                    "extensibilityLibraryConfiguration": [
                      {
                        "name": "Default extensibility library",
                        "enabled": true,
                        "id": "dc4f961b-dbe0-44b4-982d-5776bf99d015"
                      }
                    ],
                    "paging": {
                      "itemsCountPerPage": 10,
                      "pagingRange": 5,
                      "showPaging": true,
                      "hideDisabled": true,
                      "hideFirstLastPages": false,
                      "hideNavigation": false,
                      "useNextLinks": false
                    },
                    "layoutProperties": {
                      "isCompact": false,
                      "showFileIcon": true,
                      "enablePreview": false,
                      "preferedCardNumberPerRow": 3,
                      "columnSizePercentage": 33,
                      "documentCardFields": [
                        {
                          "name": "Title",
                          "field": "title",
                          "value": "{{slot item @root.slots.Title}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Location",
                          "field": "location",
                          "value": "<a style=\"color:{{@root.theme.palette.themePrimary}};font-weight:600;font-family:'{{@root.theme.fonts.small.fontFamily}}'\" href=\"{{SPSiteUrl}}\">{{SiteTitle}}</a>",
                          "useHandlebarsExpr": true,
                          "supportHtml": true
                        },
                        {
                          "name": "Tags",
                          "field": "tags",
                          "value": "<style>\n\t.tags {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t }\n\t.tags i { \n\t\tmargin-right: 5px; \n\t}\n\t.tags div {\n\t\tdisplay: flex;\n\t\tflex-wrap: wrap; \n\t\tjustify-content: flex-end; \n\t}\n\t.tags div span {\n\t\ttext-decoration: underline; \n\t\tmargin-right: auto; \n\t}\n </style>\n\n{{#if (slot item @root.slots.Tags)}}\n\t<div class=\"tags\">\n\t\t<pnp-icon data-name=\"Tag\" aria-hidden=\"true\" data-theme-variant=\"{{JSONstringify @root.theme}}\"></pnp-icon>\n\t\t<div>\n\t\t\t{{#each (split (slot item @root.slots.Tags) \",\") as |tag| }}\n\t\t\t\t<span>{{trim tag}}</span>\n\t\t\t{{/each}}\n\t\t</div>\n\t</div>\n{{/if}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": true
                        },
                        {
                          "name": "Preview Image",
                          "field": "previewImage",
                          "value": "{{slot item @root.slots.PreviewImageUrl}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Preview Url",
                          "field": "previewUrl",
                          "value": "{{slot item @root.slots.PreviewUrl}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Date",
                          "field": "date",
                          "value": "{{getDate (slot item @root.slots.Date) 'LL'}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Url",
                          "field": "href",
                          "value": "{{slot item @root.slots.PreviewUrl}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Author",
                          "field": "author",
                          "value": "{{slot item @root.slots.Author}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Profile Image Url",
                          "field": "profileImage",
                          "value": "/_layouts/15/userphoto.aspx?size=L&username={{getUserEmail (slot item @root.slots.UserEmail)}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "File Extension",
                          "field": "fileExtension",
                          "value": "{{slot item @root.slots.FileType}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        },
                        {
                          "name": "Is Folder",
                          "field": "isContainer",
                          "value": "{{slot item @root.slots.IsFolder}}",
                          "useHandlebarsExpr": true,
                          "supportHtml": false
                        }
                      ]
                    },
                    "itemSelectionProps": {
                      "allowItemSelection": false,
                      "selectionMode": "AsDataFilter",
                      "allowMulti": false,
                      "valuesOperator": "or"
                    }
                  },
                  "serverProcessedContent": {
                    "htmlStrings": [],
                    "searchablePlainTexts": [],
                    "links": [],
                    "imageSources": []
                  }
                }
              }
            ]
          }
        ]
      },
      {
        "layout": "oneColumn",
        "id": "2",
        "emphasis": "none",
        "columns": [
          {
            "id": "1",
            "width": 12,
            "webparts": [
              {
                "id": "6248c4b4-5d11-ffff-987e-ffff90e3e9ff",
                "webPartType": "c70391ea-0b10-4ee9-b2b4-006d3fcad0cd",
                "data": {
                  "audiences": [],
                  "dataVersion": "2.2",
                  "description": "Show a collection of links to content such as documents, images, videos, and more in a variety of layouts with options for icons, images, and audience targeting.",
                  "title": "Quick links",
                  "properties": {
                    "isMigrated": true,
                    "layoutId": "CompactCard",
                    "shouldShowThumbnail": true,
                    "imageWidth": 100,
                    "hideWebPartWhenEmpty": true,
                    "dataProviderId": "QuickLinks",
                    "webId": "00000000-0000-0000-0000-000000000000",
                    "siteId": "00000000-0000-0000-0000-000000000000",
                    "items": [
                      {
                        "thumbnailType": 3,
                        "id": 1,
                        "description": "",
                        "altText": "",
                        "sourceItem": {
                          "itemType": 2,
                          "fileExtension": "",
                          "progId": ""
                        }
                      }
                    ],
                    "listLayoutOptions": {
                      "showDescription": false,
                      "showIcon": true
                    },
                    "buttonLayoutOptions": {
                      "showDescription": false,
                      "buttonTreatment": 2,
                      "iconPositionType": 2,
                      "textAlignmentVertical": 2,
                      "textAlignmentHorizontal": 2,
                      "linesOfText": 2
                    },
                    "waffleLayoutOptions": {
                      "iconSize": 1,
                      "onlyShowThumbnail": false
                    }
                  },
                  "serverProcessedContent": {
                    "htmlStrings": [],
                    "searchablePlainTexts": [
                      {
                        "key": "items[0].title",
                        "value": "Test Website"
                      }
                    ],
                    "links": [
                      {
                        "key": "baseUrl",
                        "value": "/sites/xxx"
                      },
                      {
                        "key": "items[0].sourceItem.url",
                        "value": "https://www.testsite.org"
                      }
                    ],
                    "imageSources": [
                      {
                        "key": "items[0].rawPreviewImageUrl",
                        "value": "https://www.testsite.org/images/Logo.png"
                      }
                    ],
                    "componentDependencies": [
                      {
                        "key": "layoutComponentId",
                        "value": "706e33c8-af37-4e7b-9d22-6e5694d92a6f"
                      }
                    ],
                    "customMetadata": [
                      {
                        "key": "items[0].rawPreviewImageUrl",
                        "value": {
                          "fixedwidth": "100"
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

Thanks for looking into this!

gautamdsheth added a commit to gautamdsheth/powershell that referenced this issue Feb 10, 2023
gautamdsheth added a commit that referenced this issue Feb 11, 2023
Fix #2775: issue with complex JSON payload in REST methods
@gautamdsheth
Copy link
Collaborator

hi @SjoerdV , have merged a change which should fix your issue !

Can you please give it a try with tomorrow's nightly build ?

Please note that it requires PowerShell 7.2 or later version to be installed first.

Would love to know the answer , thanks !!

@SjoerdV
Copy link
Author

SjoerdV commented Feb 12, 2023

I have tried it with nightly 2.0.12 on pwsh 7.3.2. Now the error is:

The maximum number of bytes allowed to be read from the stream has been exceeded. After the last read operation, a total of 1049600 bytes has been read from the stream; however a maximum of 1048576 bytes is allowed.

This is exactly 1024 bytes difference (but the actual stream may be longer), so 'no sigar' I am afraid

@SjoerdV
Copy link
Author

SjoerdV commented Feb 16, 2023

@gautamdsheth Could you reopen please, this issue seems not to be truly 'fixed'. Thanks!

@SjoerdV
Copy link
Author

SjoerdV commented Feb 24, 2023

My bad, while I only got the update PATCH to work with the -Raw parameter filled with a single JSON string, (an PSObject would not go through, with the error above )

It seems very important to feed the -Content parameter a single string. I was feeding it an array of strings (which prints just fine in the console) but always return this cryptic error message:

[page] An unexpected 'StartArray' node was found when reading from the JSON reader. A 'StartObject' node was expected.

Again when printing the array variable to screen it seemed like regular json, but it wasn't ;-)
All fine now! Case closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants