Error {type: 'INVALID_PARAMETERS', reason: 'userId is not correct'} after joining meeting

Meeting SDK Type and Version
@zoomus/websdk”: “^2.17.0”
Meeting SDK Component View

Description
I’m trying to integrate SDK into my app (react on frontend, nestJS on backend).
Generating signature

  generateSignature(meetingNumber: string, role: number): string {
    const iat = Math.round(new Date().getTime() / 1000) - 30;
    const exp = iat + 60 * 60 * 2;

    const oHeader = { alg: 'HS256', typ: 'JWT' };
    const oPayload = {
      appKey: this.configService.get('ZOOM_MEETING_SDK_KEY'),
      sdkKey: this.configService.get('ZOOM_MEETING_SDK_KEY'),
      mn: meetingNumber,
      role,
      iat,
      exp,
      tokenExp: iat + 60 * 60 * 2,
    };

    const sHeader = JSON.stringify(oHeader);
    const sPayload = JSON.stringify(oPayload);
    const signature = KJUR.jws.JWS.sign(
      'HS256',
      sHeader,
      sPayload,
      this.configService.get('ZOOM_MEETING_SDK_SECRET'),
    );
    console.log(signature);
    return signature;
  }

Getting Oauth Token and Creating meeting:

  async createMeeting(
    topic: string,
  ): Promise<{ meetingId: string; password: string }> {
    const endpoint = `${this.baseURL}/users/me/meetings`;
    const token = await this.getToken();
    const headers = {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    };

    const startTime = new Date();
    startTime.setMinutes(startTime.getMinutes() + 1);

    const body = {
      topic,
      type: 2, // 2 for Scheduled Meeting
      start_time: startTime.toISOString(),
      duration: 60, // Duration in minutes
      settings: {
        join_before_host: true, // Enable 'Join Before Host'
        waiting_room: false,
        host_video: true,
        participant_video: true,
      },
    };

    try {
      const response = await this.httpService
        .post(endpoint, body, { headers })
        .toPromise();
      console.log(response.data);
      return {
        meetingId: response.data.id.toString(),
        password: response.data.password,
      };
    } catch (error) {
      console.log(error);
      throw new Error(`Failed to create Zoom meeting: ${error.message}`);
    }
  }

  async getToken(): Promise<any> {
    const url = `https://zoom.us/oauth/token?grant_type=account_credentials&account_id=${this.configService.get(
      'ZOOM_OAUTH_ACCOUNT_ID',
    )}`;
    const authHeader = `Basic ${Buffer.from(
      `${this.configService.get(
        'ZOOM_OAUTH_CLIENT_ID',
      )}:${this.configService.get('ZOOM_OAUTH_CLIENT_SECRET')}`,
    ).toString('base64')}`;

    try {
      const response = await this.httpService
        .post(url, null, {
          headers: {
            Authorization: authHeader,
            'Content-Type': 'application/x-www-form-urlencoded',
          },
        })
        .pipe(map((res) => res.data))
        .toPromise();

      return response.access_token;
    } catch (error) {
      throw new Error(`Error while fetching Zoom token: ${error.message}`);
    }
  }

Joining meeting with SDK:

const VideoCall = () => {
  const client = ZoomMtgEmbedded.createClient();
  const user = useAppSelector(getUserSelector);

  const meetingNumber = '84039451194';
  const passWord = 'xMFkW4';
  const role = 0;
  const userName = user.firstName || 'Test';
  const userEmail = user.email || 'test@example.com';
  const [requestSignature, { data: signatureRes }] = useGetSignatureMutation();

  function startMeeting(signature: string) {
    const meetingSDKElement = document.getElementById('meetingSDKElement');
    const meetingSDKChatElement = document.getElementById(
      'meetingSDKChatElement'
    );

    if (!meetingSDKElement) {
      return;
    }

    try {
      client.init({
        debug: true,
        zoomAppRoot: meetingSDKElement,
        language: 'en-US',
        customize: {
          meetingInfo: [
            'topic',
            'host',
            'mn',
            'pwd',
            'telPwd',
            'invite',
            'participant',
            'dc',
            'enctype',
          ],
          video: {
            popper: {
              disableDraggable: true,
            },
            isResizable: false,
            viewSizes: {
              default: {
                width: 1000,
                height: 600,
              },
              ribbon: {
                width: 300,
                height: 700,
              },
            },
          },
          chat: {
            popper: {
              disableDraggable: true,
              anchorElement: meetingSDKChatElement,
              placement: 'top',
            },
          },
          toolbar: {
            buttons: [
              {
                text: 'Custom Button',
                className: 'CustomButton',
                onClick: () => {
                  console.log('custom button');
                },
              },
            ],
          },
        },
      });

      client.join({
        signature,
        sdkKey: process.env.NX_ZOOM_KEY,
        meetingNumber,
        password: passWord,
        userName,
        userEmail,
        success: () => {
          console.error('success');
        },
        error: () => {
          console.error('error');
        },
      });
    } catch (error) {
      console.log('join', error);
    }
  }

  const getSignature = async (e: React.MouseEvent<HTMLElement>) => {
    e.preventDefault();
    try {
      await requestSignature({
        meetingNumber,
        role,
      })
        .unwrap()
        .then((res) => {
          console.log('RES', res);
          startMeeting(res.signature);
        })
        .catch((error) => {
          console.error(error);
        });
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <>
      <h1>Zoom Meeting</h1>
      {/* For Component View */}
      <div id="meetingSDKElement">
        {/* Zoom Meeting SDK Component View Rendered Here */}
      </div>
      <button onClick={getSignature}>Join Meeting</button>
      <div id="meetingSDKChatElement"></div>
    </>
  );
};
type or paste code here

Error?
After I’m pressing Join meeting user connects, but app is crashing with error
{
“type”: “INVALID_PARAMETERS”,
“reason”: “userId is not correct”
}
Also, after that if I tried to press Leave Meeting and got an error
{
“type”: “IMPROPER_MEETING_STATE”,
“reason”: “closed”
}

Troubleshooting Routes
I walked through documentation again, since user is joining, I guess signature is generating fine.
Also, I did everything on sample app first, same errors.
Thinking problem is somewhere in meeting params, but can’t figure out.
I’ve got meeting details from API, if it helps:

{
    "uuid": "+CDYlTo0ToCq0m5hHjhRKw==",
    "id": 84039451194,
    "host_id": "O9ijUpr2TB-ZX3jw3PH3mw",
    "host_email": "dkononov.zp@gmail.com",
    "assistant_id": "",
    "topic": "hi",
    "type": 2,
    "status": "started",
    "start_time": "2023-10-13T09:21:00Z",
    "duration": 60,
    "timezone": "Europe/Kiev",
    "agenda": "",
    "created_at": "2023-10-13T09:21:00Z",
    "start_url": "https://us05web.zoom.us/s/84039451194?zak=eyJ0eXAiOiJKV1QiLCJzdiI6IjAwMDAwMSIsInptX3NrbSI6InptX28ybSIsImFsZyI6IkhTMjU2In0.eyJhdWQiOiJjbGllbnRzbSIsInVpZCI6Ik85aWpVcHIyVEItWlgzanczUEgzbXciLCJpc3MiOiJ3ZWIiLCJzayI6IjAiLCJzdHkiOjEsIndjZCI6InVzMDUiLCJjbHQiOjAsIm1udW0iOiI4NDAzOTQ1MTE5NCIsImV4cCI6MTY5NzE5NjE2NywiaWF0IjoxNjk3MTg4OTY3LCJhaWQiOiJHUWNmNHlCN1ROYWwtZ3BjTDJsYTlBIiwiY2lkIjoiIn0.ALIiTnrd56lT2A3Ua8GnqospKdHhlyIoHimUvOR0ZgE",
    "join_url": "https://us05web.zoom.us/j/84039451194?pwd=zHN2y5Nk8DHtsFJPgbDkhaetLLi4JH.1",
    "password": "xMFkW4",
    "h323_password": "751674",
    "pstn_password": "751674",
    "encrypted_password": "zHN2y5Nk8DHtsFJPgbDkhaetLLi4JH.1",
    "settings": {
        "host_video": true,
        "participant_video": true,
        "cn_meeting": false,
        "in_meeting": false,
        "join_before_host": true,
        "jbh_time": 0,
        "mute_upon_entry": false,
        "watermark": false,
        "use_pmi": false,
        "approval_type": 2,
        "audio": "voip",
        "auto_recording": "none",
        "enforce_login": false,
        "enforce_login_domains": "",
        "alternative_hosts": "",
        "alternative_host_update_polls": false,
        "close_registration": false,
        "show_share_button": false,
        "allow_multiple_devices": false,
        "registrants_confirmation_email": true,
        "waiting_room": false,
        "request_permission_to_unmute_participants": false,
        "registrants_email_notification": true,
        "meeting_authentication": false,
        "encryption_type": "enhanced_encryption",
        "approved_or_denied_countries_or_regions": {
            "enable": false
        },
        "breakout_room": {
            "enable": false
        },
        "internal_meeting": false,
        "continuous_meeting_chat": {
            "enable": false,
            "auto_add_invited_external_users": false
        },
        "participant_focused_meeting": false,
        "push_change_to_calendar": false,
        "alternative_hosts_email_notification": true,
        "show_join_info": false,
        "device_testing": false,
        "focus_mode": false,
        "enable_dedicated_group_chat": false,
        "private_meeting": false,
        "email_notification": true,
        "host_save_video_order": false,
        "sign_language_interpretation": {
            "enable": false
        },
        "email_in_attendee_report": false
    },
    "pre_schedule": false
}

What am I missing?

Hi, @dkononov.zp,

Are you using the user’s email or ID to join the meeting? Based on the error message, it seems that the UserID is the issue. Can you confirm if you tested joining the meeting as a guest? If so, please share the result. It would also be helpful if you could let us know what does work as well.

Hi! I’m using

 client.join({
        signature,
        sdkKey: process.env.NX_ZOOM_KEY,
        meetingNumber,
        password: passWord,
        userName,
        userEmail, // not required
      });

where signature generated on backend, sdkKey - Client ID from meeting sdk app from market, meeting number and password from API responce, and then user name and email from user’s data in my App. I tried to join without email too, since according to documentation is not required, but got the same result.
That’s all I’m using to join.

You’re correct, what I’m trying to achieve, is that users join as guests. So at this moment, user is joining, but receiving an error. Tried to join with 2 different users, it’s working with error, they see eachother at meeting. But if after that I try, for example, click “minimize” on component, I receive same error. I can’t understand what is that userId and where’s that error coming from, since I’m not passing any ID’s for my users?

I am having the exact issues as OP. What does it means for “userId is not correct” and Improper_meeting_state error?

Best regards,

@donte.zoom Hi, can you help with any ideas where this errors can come from?

@dkononov.zp,

At first glance, I don’t see any issues with how you are initializing and joining the meeting. Additionally, I don’t see any issues with the join payload you included. As a next step, you can test the join flow using the sample apps provided below. I recommend comparing the generated values with the ones you are obtaining in the sample to see if anything stands out. Once you successfully join, you can manually copy values from the sample app (such as the SDK JWT and client.join property values) into your application to help identify any potential issues.

Below I’ve included all of the links to the sample applications you can reference :

Sample React Zoom Meeting SDK App :

Zoom Meeting SDK Auth Endpoint sample

Troubleshooting Zoom Meeting SDK signature validation :

Thank you for your response @donte.zoom
I started integration from Sample apps.

So on Client view with both backend apps (Zoom Sample and my version) I don’t have any errors, but 4 warnings. But I can’t use Client view, cause somehow it doesn’t work with React 18.2 …

And on Component view from sample app I’ve got same errors.
Another thing is that I tried to add “success” and “error” callbacks on client.join for component view, since they are in documentation and none of them shown any result, not sure why, maybe that’s some sort of symptom too?

Should there be some difference on backend, on creating signature or scheduling meeting for Client and Component views? Haven’t seen anything in docs.

Interesting, that should definitely work. Can you share how you added “success” and “error” callbacks on client.join for component view ?

There is no difference on the backend, on creating signatures or scheduling meeting for Client and Component views. You should be able to join with no problem.

Are you saying that you can not join the meeting when using the Sample Component View App?

@donte.zoom I’ve tried the simplest way to see at least some result, but nothing.

    client.join({
      signature: signature,
      sdkKey: sdkKey,
      meetingNumber: meetingNumber,
      password: passWord,
      userName: userName,
      userEmail: userEmail,
      success: () => {
        console.log('success');
      },
      error: () => {
        console.log('error');
      },
    });

And on Client view “success” callback works fine.

About your second question, as I wrote in my first message, users can connect to meeting from both sample app and mine (at least I tried connecting 2 users from 2 browsers, saw both in meeting), but in both ways I’m receving same error in console.

Also, who knows, maybe it will somehow help to troubleshoot. On joining on component view from sample app I’m receiving some logs in devtools:

SET_CODEC_MODE 9
VP9?: true AMD?: true AMDdecodecheck: false isenbaleHD:true enable720p?: true capacityfor720: false

and right after this I’m receiving an error.

And one more. If I try to change size of Zoom Component, dragging window corner, then I receive same error in console. Not sure how could that be connected with userId :roll_eyes: Why can resize provoke same error?

Okay, I am not able to reproduce that behavior on my end. Let me upgrade to the latest versions to see if this behavior is reproducible on my end.

@dkononov.zp

That log is just providing information about the browser’s video capabilities, hardware acceleration, and support for different video codecs and resolutions.

What error are you receiving, can you share a screenshot?

@donte.zoom It’s the same on join and on resize
image
And this one on “Leave meating”
image

@donte.zoom Hello! Maybe you have any updates on this topic? My project was postponed, but now I’m returning to it again, if you have any ideas, I would be grateful.

Hey, @dkononov.zp ,

Thanks for following up here. that userID error might be just an issue with SDK our logging. I always see that error when I successfully join a meeting/webinar. Are you able to successfully join the meeting even when that error is observed?

@donte.zoom thank you, well, yes, I could join meeting with that error, so that was not that bad.
But now I have bigger problem. I’ve deployed my app and I can’t connect from there.
I have two types of errors in console:
Uncaught TypeError: Cannot read properties of undefined (reading ‘enumerateDevices’)
and
Uncaught ReferenceError: JsMediaSDK_Instance is not defined
So I see “joining meeting” stuck and that’s all.
Code for init/join is the same as it was and it still works on local enviroment.

@dkononov.zp ,

Please see this thread and me know if this helps :

Just in case it will help anyone, problem was in deployment without SSL.

@donte.zoom Can you please help with one more question, now when I’m trying to test two meetings at one time, I found out it’s impossible, since I’m hosting it with one account. I’ve found Concurrent meetings - #8 by tommy this one, is this still a best practice? There’s no option to create users dynamically, at least to do it from my backend? Or on some pro/business/super-mega-pro accout to host more meetings?
Just can’t understand, what’s the point of videocall app, where only one call is possible at the time. (Also, this probably should be written on the first page here Zoom Meeting SDK)

And how should it actually work, I should create user for every user, that’ll schedule meeting and use his own credentials to schedule meet?
And user creation is only available on Pro and better (?) account? But what are limitations for those pricing plans for user quantity or anything else? Can’t see it Plans & Pricing for Zoom One | Zoom here.

I am facing the exact same two issues when joining , resizing and while leaving the meeting, that the user ID is not correct, I tried to use the sample app to create a meeting however, Unfortunately though I am able ti join the meeting, this error pops in the screen whenever I try some interactive functions with the zoom meet window,

It would be great if anyone could come up with a solution for this

1 Like

Hey @donte.zoom , I am also getting same two errors in my React web app.
Whenever I try to join meeting in component view/ whenever I try to resize the meet window by dragging bottom-right corner, I get callback errors and logs as follows -

Errors I am getting -

VP9?: true AMD?: false AMDdecodecheck: true isenbaleHD:true enable720p?: false capacityfor720: false

Uncaught (in promise) 
reason: "userId is not correct"
type: "INVALID_PARAMETERS" // get this error whenever I join meet or try to resize component view window


reason: "closed"
type: "IMPROPER_MEETING_STATE" // get this error whenever I close the meet by pressing "End meeting for all"

Here’s the code snippet -

import ZoomMtgEmbedded from "@zoomus/websdk/embedded"

const client = ZoomMtgEmbedded.createClient()
let meetingSDKElement = document.getElementById("meetingSDKElement")
client
        .init({
          zoomAppRoot: meetingSDKElement,
          language: "en-US",
          customize: {
            video: {
              isResizable: true,
              viewSizes: {
                default: {
                  width: 1000,
                  height: 600,
                },
                ribbon: {
                  width: 300,
                  height: 700,
                },
              },
            },
          },
        })
        .then(() => {
          client.join({
            signature: sign,
            sdkKey: sdkClientId,
            meetingNumber: meetingId,
            password: meetingPassword,
            userName: user_name,
            zak: zakToken, // the host's zak token
            success: (success) => {
              console.log("============= Zoom join success", success)
            },
            error: (errorMsg) => {
              console.log("============= Zoom join Error", errorMsg)
            },
          })
        })
        .catch((error) => {
          console.log("============= Zoom init error", error)
        })

I see many people getting this error on this forum. Has anybody found any solution for this?

It is possible to run a concurrent meeting Zoom, but depends on your account and license type. Per the support documentation:

"Each Basic user and Licensed user on a Pro account is limited to hosting only 1 meeting at a time.

Licensed users on Business, Education, and Enterprise accounts can host up to 2 meetings at the same time. "

Resource:

Can you share more details about your use case ? Based on the information shared, it sounds like you may want to consider leveraging the custCreate workflow. Users created via custCreate do not have passwords and will not have the ability to log into the Zoom Web Portal or the Zoom Client. These users can still host and join meetings using the start_url and join_url respectively. To use this option, you must contact the ISV Team.

This dependent on your use case, please share more details as this will help identify the best workflow.

You can add up to 9999 Basic (free) users to your Zoom account. Please see our Frequently asked questions for admins for more details on this topic.

Resource:
Frequently asked questions for admins