Skip to content

fix: Fix BatchItem deserialization for non-string primitive values#367

Open
jvaesteves wants to merge 1 commit into
microsoftgraph:mainfrom
jvaesteves:main
Open

fix: Fix BatchItem deserialization for non-string primitive values#367
jvaesteves wants to merge 1 commit into
microsoftgraph:mainfrom
jvaesteves:main

Conversation

@jvaesteves

Copy link
Copy Markdown

Overview

At this moment, when making any BatchRequests, the any primitive value in the results that are not strings are not being properly deserialized. That is because the case grouping was not done properly, and it skips all possible returns inside the switch block, falling into the return nil, nil loc. This simple change fixes this by properly collapsing these options into a single case, separate by commas.

Testing

  • To replicate my original scenario, I did find this issue by batching mutiple client.Drives().ByDriveId(driveID).Items().ByDriveItemId(fileID) in a single batch
  • When selecting any non-string values, like size in my case, these values were returned nil
  • With this change, they return with their expected type

You can use the following snippet to replicate this test. If everything goes as expected, it should not panic at all

requestConfig := &msgraph_drives.ItemItemsDriveItemItemRequestBuilderGetRequestConfiguration{
	QueryParameters: &msgraph_drives.ItemItemsDriveItemItemRequestBuilderGetQueryParameters{
		Select: ["size"], // anything else, but this was my main issue
	},
}

driveItemIds := []string{} // just add a driveItemId for any non-empty file in OneDrive/Sharepoint
driveItemIdToStepId := make(map[string]*string, len(driveItemIds))

for _, driveItemId := range driveItemIds {
	reqInfo, err := client.Drives().ByDriveId(driveID).Items().ByDriveItemId(driveItemId).ToGetRequestInformation(ctx, requestConfig)
	if err != nil {
		panic(err)
	}

	step, err := batchCollection.AddBatchRequestStep(*reqInfo)
	if err != nil {
		panic(err)
	}

	driveItemIdToStepId[driveItemId] = step.GetId()
}

batchResponse, err := batchCollection.Send(ctx, client.GetAdapter())
if err != nil {
	panic(err)
}

for _, driveItemId := range driveItemIds {
    stepID := driveItemIdToStepId[driveItemId]
    driveItem, err := msgraphcore.GetBatchResponseById[models.DriveItemable](
        batchResponse, *stepID, models.CreateDriveItemFromDiscriminatorValue,
    )
    if err != nil {
        panic(err)
    }

    if driveItem.GetSize() == nil {
        panic(fmt.Errorf("size is nil for driveItem %s", driveItemId))
    }
}

@jvaesteves
jvaesteves requested a review from a team as a code owner November 13, 2025 09:59
@jvaesteves jvaesteves changed the title fix: Collapse primitve type switch options into a single case fix: Fix BatchItem deserialization for non-string primitive values Nov 13, 2025
@sambis-mind

Copy link
Copy Markdown

We independently root-caused this exact bug in production today and can confirm both the diagnosis and the fix.

Impact in our case: we run a data-security pipeline that fetches SharePoint driveItems via $batch with $select=...,size. Graph returns "size": 22540 on the wire (verified by logging the raw HTTP response under the adapter), but after batch.SendGetBatchResponseById[models.DriveItemable], GetSize() is nil. Re-marshaling item.GetBody() shows "size": null — the value dies in deserializeValue exactly as described here: the empty case float64: matches, the switch exits (Go has no implicit fallthrough), and control reaches return nil, nil.

Reproduced on v1.2.1 through v1.4.1. Every numeric field in every batch response body is affected; strings and objects survive, which makes this easy to miss — our recorded test fixtures happened to contain no numeric assertions, so it shipped silently.

One note: the same pattern affects the value-type node case two lines below (case jsonserialization.JsonParseNode: has an empty body too, so a value-typed node also falls through to nil, nil). Might be worth folding into this PR or a follow-up.

Would be great to get this merged — happy to provide the full repro program if useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants