msgraph-sdk-go: Regression in API behavior between v0.26.0 and the newly published v0.29.0 "UpdateUser"

First Issue:

Previously using v0.26.0, the below snippet of code ran without any issue, however after upgrading to v0.29.0 I’m getting the following error "API call failed with the following error(s): \n > Message: Resource '' does not exist or one of its queried reference-property objects are not present.\n > Code: Request_ResourceNotFound\n"

The reason for calling update immediately after creating the invite is because the Invitation api does not allow a user to set the firstName (givenname) and lastName (surname) fields, so those have to be done separately as another api call.

func (gc *msgraphclient) CreateUser(u *User) (*User, error) {

	if u == nil {
		return nil, ErrUserNotSpecified
	}

	requestBody := models.NewInvitation()
	requestBody.SetInvitedUserEmailAddress(&u.Username)
	inviteRedirectUrl := fmt.Sprintf("https://portal.azure.com/%s", gc.config.TenantId)
	requestBody.SetInviteRedirectUrl(&inviteRedirectUrl)
	requestBody.SetInvitedUserDisplayName(&u.DisplayName)

	resp, err := gc.appClient.Invitations().Post(requestBody)
	if err != nil {
		return nil, err
	}

	u.Id = *resp.GetInvitedUser().GetId()
	_, err = gc.UpdateUser(u)
	if err != nil {
		log.Error("error updating user after creating invitation")
		return nil, err
	}
	return u, nil
}

func (gc *msgraphclient) UpdateUser(u *User) (*User, error) {

	if u == nil {
		return nil, ErrUserNotSpecified
	}

	requestBody := models.NewUser()
	requestBody.SetAccountEnabled(&u.AccountEnabled)
	requestBody.SetDisplayName(&u.DisplayName)
	requestBody.SetGivenName(&u.GivenName)
	requestBody.SetSurname(&u.Surname)
	requestBody.SetMail(&u.Email)

	err := gc.appClient.UsersById(u.Id).Patch(requestBody)
	if err != nil {
		return nil, err
	}

	return u, nil
}

Second Issue:

Even with the below code, which is able to successfully find the user by email, throws the same error as the first issue when trying to update existing users (both invitation & non-invitation) in the Microsoft Graph.

func (gc *msgraphclient) UpdateUser(emailAddress, firstName, lastName string) error {

	err := g.EnsureGraphForAppOnlyAuth()
	if err != nil {
		return err
	}

	targetUser, _ := gc.FindUserByEmail(emailAddress)
	targetUser.SetGivenName(&firstName)
	targetUser.SetSurname(&lastName)

	err = g.appClient.UsersById(*targetUser.GetId()).Patch(targetUser)
	if err != nil {
		return err
	}

	return nil
}

func (gc *msgraphclient) FindUserByEmail(email string) (models.Userable, error) {

	filter := fmt.Sprintf("mail eq '%s' and creationType eq 'Invitation'", email)
	fields := []string{"id", "userPrincipalName", "displayName", "givenName", "surname", "mail", "accountEnabled"}
	requestParameters := &users.UsersRequestBuilderGetQueryParameters{
		Filter: &filter,
		Select: fields,
	}
	options := &users.UsersRequestBuilderGetRequestConfiguration{
		QueryParameters: requestParameters,
	}

	resp, err := gc.appClient.Users().GetWithRequestConfigurationAndResponseHandler(options, nil)
	if err != nil {
		return nil, err
	}

	users := resp.GetValue()
	if len(users) <= 0 {
		return nil, errors.New("user not found")
	} else if len(users) > 1 {
		return nil, errors.New("duplicate users found")
	}
	msUser := users[0]

	return msUser, nil
}

Given the above, all signs point to there being a critical regression in the logic for the UpdateUser endpoint.

Just for context, I’ve tried using both the object ID and userPrincipalName as “userId” values when calling the UpdateUser method, neither makes a difference and I still get an error.

P.S - The same “UpdateUser” function above which previously executed without any issue sometimes throws the following error as well but I’m not able to consistently reproduce --> Specified HTTP method is not allowed for the request target.\n > Code: Request_BadRequest\n

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 19 (10 by maintainers)

Most upvoted comments

Thank you a lot for providing all that valuable information and helping troubleshoot! I’ll create an announcement issue so people aren’t surprised.

Could this one be caused by the user patch afterwards? Can you try to set type. To nil on this one as well please?

You were completely right, it was caused by the call to patch afterward; I didn’t notice it in my logs until you mentioned this.

Ok, so I got some updates:

  1. Setting the Type to nil for the “Write” based operations (that includes, “Create Invite”, “Update User” & “Create Group”), is a valid workaround and allows the code to run without any errors.

  2. Remember that "API call failed with the following error(s): \n > Message: Specified HTTP method is not allowed for the request target.\n > Code: Request_BadRequest\n" that I mentioned before but wasn’t able to reproduce, well I stumbled upon it again and now I’m able to reproduce. It turns out it was a bug in my code and so we can safely disregard within the context of the SDK.

Anyways, I’m able to run the code without any issues as long as I use the SetType(nil) workaround. So finally this GitHub issue is officially resolved, now we just have to wait until it’s properly fixed in the conversion library.

Thanks again for your support & patience while assisting me in getting these issues resolved.

Found the culprit! https://github.com/microsoftgraph/msgraph-sdk-go/blob/32e95517554481b1846846df8198fdab79909f76/models/entity.go#L794

Should be @odata.type and not just type. The service couple reply with a more explicit error message though… Let me try to address this quickly in the generator, sorry about that.