Bug report: `entra m365group remove` does not work
Priority
(Urgent) I can't use the CLI
Description
When we added a fix to this #6618 by adding https://github.com/pnp/cli-microsoft365/blob/b2b02aef3617e6d5d159a5cb870bf0b7d55d713e/src/request.ts#L234-L237
We introduced a new bug in entra m365group remove command.
In this command, when we remove the associated SharePoint site with the entra group, we first retrieve its full URL
https://github.com/pnp/cli-microsoft365/blob/b2b02aef3617e6d5d159a5cb870bf0b7d55d713e/src/m365/entra/commands/m365group/m365group-remove.ts#L111
and then pass it over to deleteM365GroupSite method in which the site full URL is passed as a query option in the request URL
https://github.com/pnp/cli-microsoft365/blob/b2b02aef3617e6d5d159a5cb870bf0b7d55d713e/src/m365/entra/commands/m365group/m365group-remove.ts#L165-L171
What will happen is when we retrieve and pass a SharePoint site with URL: https://aaa.bbb/ccc in the request.post processing, we will end up with URL https:/aaa.bbb/ccc as the trailing / gets removed.
Screenshot from running the entra m365group remove with debug option
Steps to reproduce
simply run entra m365group remove on any group
Expected results
should remove the group and its associated SharePoint Site without error
Actual results
Error: Invalid URI: The Authority/Host could not be parsed.
Diagnostics
Removing Microsoft 365 Group: efd8c8e3-c81a-45db-80eb-b787b64c8d78...
Existing access token bla bla bla
Request:
{
"url": "https://graph.microsoft.com/v1.0/groups/efd8c8e3-c81a-45db-80eb-b787b64c8d78?$select=groupTypes",
"method": "get",
"headers": {
"Accept": "application/json;odata.metadata=none",
"user-agent": "NONISV|SharePointPnP|CLIMicrosoft365/11.3.0",
"accept-encoding": "gzip, deflate",
"X-ClientService-ClientTag": "M365CLI:11.3.0",
"authorization": "Bearer bla bla bla
},
"responseType": "json",
"decompress": true
}
Response:
{
"url": "https://graph.microsoft.com/v1.0/groups/efd8c8e3-c81a-45db-80eb-b787b64c8d78?$select=groupTypes",
"status": 200,
"statusText": "OK",
"headers": {
"cache-control": "no-cache",
"transfer-encoding": "chunked",
"content-type": "application/json;odata.metadata=none;odata.streaming=true;IEEE754Compatible=false;charset=utf-8",
"vary": "Accept-Encoding",
"strict-transport-security": "max-age=31536000",
"request-id": "bc2533c8-6b2e-4b2e-b9e2-3a51db28b9f7",
"client-request-id": "bc2533c8-6b2e-4b2e-b9e2-3a51db28b9f7",
"x-ms-ags-diagnostic": "{\"ServerInfo\":{\"DataCenter\":\"Poland Central\",\"Slice\":\"E\",\"Ring\":\"2\",\"ScaleUnit\":\"002\",\"RoleInstance\":\"WA3PEPF000001C6\"}}",
"x-ms-resource-unit": "1",
"odata-version": "4.0",
"date": "Sun, 30 Nov 2025 21:25:19 GMT"
},
"data": {
"groupTypes": [
"Unified"
]
}
}
Getting the site URL of Microsoft 365 Group: efd8c8e3-c81a-45db-80eb-b787b64c8d78...
Existing access token bla bla bla
Request:
{
"url": "https://graph.microsoft.com/v1.0/groups/efd8c8e3-c81a-45db-80eb-b787b64c8d78/drive?$select=webUrl",
"method": "get",
"headers": {
"Accept": "application/json;odata.metadata=none",
"user-agent": "NONISV|SharePointPnP|CLIMicrosoft365/11.3.0",
"accept-encoding": "gzip, deflate",
"X-ClientService-ClientTag": "M365CLI:11.3.0",
"authorization": "Bearer bla bla bla
},
"responseType": "json",
"decompress": true
}
Response:
{
"url": "https://graph.microsoft.com/v1.0/groups/efd8c8e3-c81a-45db-80eb-b787b64c8d78/drive?$select=webUrl",
"status": 200,
"statusText": "OK",
"headers": {
"cache-control": "no-store, no-cache",
"transfer-encoding": "chunked",
"content-type": "application/json;odata.metadata=none;odata.streaming=true;IEEE754Compatible=false;charset=utf-8",
"vary": "Accept-Encoding",
"strict-transport-security": "max-age=31536000",
"request-id": "e11cd2f6-3156-4638-ac52-4259e442de4a",
"client-request-id": "e11cd2f6-3156-4638-ac52-4259e442de4a",
"x-ms-ags-diagnostic": "{\"ServerInfo\":{\"DataCenter\":\"Poland Central\",\"Slice\":\"E\",\"Ring\":\"2\",\"ScaleUnit\":\"002\",\"RoleInstance\":\"WA3PEPF000001C6\"}}",
"splogid": "4c8ddea1-9071-a000-bc03-9492eca34cd1",
"odata-version": "4.0",
"date": "Sun, 30 Nov 2025 21:25:20 GMT"
},
"data": {
"webUrl": "https://tenanttocheck.sharepoint.com/sites/Group533673/Shared%20Documents"
}
}
SPO URL previously retrieved https://tenanttocheck.sharepoint.com. Returning...
Deleting the group site: 'https://tenanttocheck.sharepoint.com/sites/Group533673'...
Existing access token bla bla bla
Request:
{
"url": "https://tenanttocheck-admin.sharepoint.com/_api/GroupSiteManager/Delete?siteUrl='https:/tenanttocheck.sharepoint.com/sites/Group533673'",
"method": "post",
"headers": {
"Accept": "application/json;odata=nometadata",
"user-agent": "NONISV|SharePointPnP|CLIMicrosoft365/11.3.0",
"accept-encoding": "gzip, deflate",
"X-ClientService-ClientTag": "M365CLI:11.3.0",
"authorization": bla bla bla
},
"responseType": "json",
"decompress": true
}
Request error:
{
"url": "https://tenanttocheck-admin.sharepoint.com/_api/GroupSiteManager/Delete?siteUrl='https:/tenanttocheck.sharepoint.com/sites/Group533673'",
"status": 500,
"statusText": "Internal Server Error",
"headers": {
"cache-control": "private, max-age=0",
"transfer-encoding": "chunked",
"content-type": "application/json;odata=nometadata;streaming=true;charset=utf-8",
"expires": "Sat, 15 Nov 2025 21:25:22 GMT",
"last-modified": "Sun, 30 Nov 2025 21:25:22 GMT",
"vary": "Origin",
"p3p": "CP=\"ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI\"",
"x-networkstatistics": "0,4194720,0,0,291,26345,26345,141732",
"x-sharepointhealthscore": "1",
"x-sp-serverstate": "ReadOnly=0",
"dataserviceversion": "3.0",
"spclientservicerequestduration": "68",
"x-aspnet-version": "4.0.30319",
"isocdi": "0",
"x-databoundary": "NONE",
"x-1dscollectorurl": "https://mobile.events.data.microsoft.com/OneCollector/1.0/",
"x-ariacollectorurl": "https://browser.pipe.aria.microsoft.com/Collector/3.0/",
"sprequestguid": "4c8ddea1-70a4-a000-bc03-95fc603132be",
"request-id": "4c8ddea1-70a4-a000-bc03-95fc603132be",
"ms-cv": "od6NTKRwAKC8A5X8YDEyvg.0",
"splogid": "4c8ddea1-70a4-a000-bc03-95fc603132be",
"alt-svc": "h3=\":443\";ma=86400",
"strict-transport-security": "max-age=31536000",
"x-frame-options": "SAMEORIGIN",
"content-security-policy": "frame-ancestors 'self' teams.microsoft.com *.teams.microsoft.com *.skype.com *.teams.microsoft.us local.teams.office.com teams.cloud.microsoft *.office365.com goals.cloud.microsoft *.powerapps.com *.powerbi.com *.yammer.com engage.cloud.microsoft word.cloud.microsoft excel.cloud.microsoft powerpoint.cloud.microsoft *.officeapps.live.com *.office.com *.microsoft365.com m365.cloud.microsoft *.cloud.microsoft *.stream.azure-test.net *.dynamics.com *.microsoft.com onedrive.live.com *.onedrive.live.com securebroker.sharepointonline.com;",
"x-powered-by": "ASP.NET",
"microsoftsharepointteamservices": "16.0.0.26705",
"x-content-type-options": "nosniff",
"x-ms-invokeapp": "1; RequireReadOnly",
"x-cache": "CONFIG_NOCACHE",
"x-msedge-ref": "Ref A: 91C8E403356B468E81B7A71DD7AB02A5 Ref B: BER231070920023 Ref C: 2025-11-30T21:25:21Z",
"date": "Sun, 30 Nov 2025 21:25:21 GMT"
},
"error": {
"odata.error": {
"code": "-1, System.UriFormatException",
"lang": "en-US",
"value": "Invalid URI: The Authority/Host could not be parsed."
}
}
}
}
Error
at EntraM365GroupRemoveCommand.handleRejectedODataJsonPromise (file:///C:/workspace/repo/cli-microsoft365/dist/Command.js:286:27)
at removeGroup (file:///C:/workspace/repo/cli-microsoft365/dist/m365/entra/commands/m365group/m365group-remove.js:58:22)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async EntraM365GroupRemoveCommand.commandAction (file:///C:/workspace/repo/cli-microsoft365/dist/m365/entra/commands/m365group/m365group-remove.js:67:17)
icrosoft365/dist/cli/cli.js:199:9)
at async file:///C:/workspace/repo/cli-microsoft365/dist/index.js:16:5
at async file:///C:/workspace/repo/cli-microsoft365/dist/index.js:4:1
Timings:
api: 2616.5362ms
core: 18.3651ms
command: 7091.3821ms
options: 0.1725ms
total: 7111.5492ms
validation: 1.0216ms
Error: Invalid URI: The Authority/Host could not be parsed.
CLI for Microsoft 365 version
v11.2.0
nodejs version
v22
Operating system (environment)
Windows
Shell
PowerShell
cli doctor
No response
Additional Info
No response
@pnp/cli-for-microsoft-365-maintainers the bug is quite easy but the fix may be tricky.
I was thinking to add a check to avoid https:// and http:// in removing trailing / method in the request.ts but not sure if this is optimal.
Any other suggestions
Nice catch @Adam-it! Instead, can't we just encode the query parameter?
?siteUrl='${formatting.encodeQueryParameter(url)}'
Good idea. will recheck if it works.
Hope this was the only command impacted by this change. Maybe we should search for similar API usage in which siteUrl or url or other ....Url is used as a query option in the url of the request
We should always encode query parameters where possible. You never know what value is passed that might break the URL.