stream.renderVideo() error on connected user

Hello, I am trying to use Video SDK for my new project, and getting following error while second user is connected with client.join(). First user is already connected, and started the video, and getting the error on second user joins.

reason: “user is not send video” ​,

Which Web Video SDK version?
Downloaded zoom-instant-sdk-web-1.0.2, but ZoomInstant.VERSION is 1.0.0.

To Reproduce(If applicable)
Steps to reproduce the behavior:

  1. first user join()
  2. first user starts video
  3. second user join()
  4. Gets error on ‘video-active-change’ event.

Device (please complete the following information):

  • Device: Macbook
  • OS: Big Sur v. 11.2.1
  • Browser: Chrome
  • Browser Version: Version 89.0.4389.90 (Official Build) (x86_64)

Hey @ktae13 ,

Thank you for reporting this issue, we are investigating it and will report back once we find the root cause. (CS-3209) :slight_smile:


Hi @tommy

Thanks for the reply. I just wanted to confirm if this was the (known) issue with the current version of SDK, and how long it would take to fix the issue. I am creating a prototype for new project, and need to have (fully) functional zoom video sdk asap.

Thank you,

1 Like

Guys, I also want to mention that I am also having the same exact issue …

Let me also mention some additional context…

Your documentation is a bit misleading…

The link below under the heading Render Video reflects that on the video-active-change event that is emitted that the payload object when payload.state === 'Active' should include a property called id (e.g: … However, from my testing the object DOES NOT return id it returns userId … I have also tried using the userId but same error as above.

Please resolve so I can also test your SDK.


For example…

1 Like

Hey @ktae13 ,

We are looking into this to see if it is an issue with the current version.

However, it seems like you may be trying to stream user 2’s video before they turn their webcam on. Can you confirm?


Thanks for your feedback @jremi , we will get this docs fixed. (DEVELOPERS-1067)


Thank you, I’m kinda stuck for now until I can get some additional insight from your dev team.


Understood @jremi , we will work to resolve this asap.


1 Like

I am not trying to stream user 2’s video. When user 2 joins the meeting, I am getting video-active-change message for user 1, and getting the error while processing user 1’s video on user 2’s screen.

@jremi I also had issues with the misleading doc. For example, renderVideo's parameters on the example is wrong, but SDK reference has right values(Stream | @zoomus/instantsdk)


@ktae13 … the SDK reference looks good.

Either way, when I do the stream.startVideo() it fires off the event on the .on('video-active-change') which is GOOD and the payload that comes in DOES have {state: "Active", userId: "XXXXXXXXX"}

My webcam light turns on the macbook…

The problem is that when I run for example:
await stream.renderVideo(canvas, payload.userId, 300, 200, 0, 0, 1)

The canvas shows nothing. I have verified that I have the the corect canvas element being passed in …

For example:

const canvas = document.querySelector("#canvas-video-capture1");

This canvas is a valid DOM element on the page.

Any ideas?

@jremi That is also my another problem.
Mentioning @tommy just in case. :slight_smile:

Here’s couple scenarios.
[I’m the only one in the meeting]

  1. Join()
  2. startVideo(‘canvas id’) ==> video started, but not render on canvas.
  3. got video-active-change
    3.1. calling stream.renderVideo(‘canvas’…) => start render on canvas.

[Two players in the meeting]

  1. Join u1
  2. Join u2
  3. u1 startVideo
  4. u2 gets video-active-chage, but u1 doesn’t get it.
    4.1 so, video is rendered on u2 screen, but not on u1 screen.
  5. When u2 leaves, u1 gets video-active-chage and displays its video now.

@jremi I was able to render video after startVideo.
What you need to do is

await, userId, 300, 200, 0, 0, 1);

It seems like video-active-change is not for MY video, but for others only.

1 Like

Hey @ktae13 ,

Thanks for sharing this.

@jremi , are you still stuck?


@tommy @ktae13

Yes, I am still stuck.

When I run …

  • await stream.startVideo() is triggering the video-active-change event. :white_check_mark:

  • Inside the video-active-change event handler the payload object is emitted with payload.state === ‘Active’` :white_check_mark:

  • Inside this conditional check for the Active state the renderVideo method is called.

Example: await stream.renderVideo(canvas, userId, 300, 200, 0, 0, 1);

Canvas is the DOM element of the canvas on the page. This is assigned via querySelector. The userId is provided via the emitted payload object in the event payload.userId

  • The MacBook green camera light turns ON :white_check_mark:.

DESPITE all of the above NOTHING is rendered to the canvas. I get no video appearing on the page. :no_entry_sign:

Example snippets of the most critical parts.:

// Global button handler function to start video
window.startVideo = async function () {
  if (!stream.isCapturingVideo()) {
    console.log("Starting video...");
    await stream.startVideo("canvas-video-capture1");

// Client event handler for video-active-change event.
client.on("video-active-change", async (payload) => {
  console.log("Zoom video-active-change:", payload);
  if (payload.state === "Active") {
    const canvas = document.querySelector("#canvas-video-capture1");
    await stream.renderVideo(canvas, payload.userId, 300, 200, 0, 0, 1);
  } else if (payload.state === "Inactive") {
    await stream.stopRenderVideo();


UPDATE: I have SOLVED my issue.

I needed to use <canvas> tag. I was using accidentally <div>

Thank you!

1 Like

Hey @jremi ,

Happy to hear you resolved your issue. :slight_smile:

We are going to be updating the docs to clear up confusion around this.


Hey @tommy,
Wonder if there’s any update on my original question, and would report more issues I have while using video sdk.

  1. Calling client.leave() throws error.
    1.1 WebSocket is already in CLOSING or CLOSED state.
    1.2 Uncaught (in promise) {type: "INVALID_OPERATION"}
  2. Calling client.join() after client.leave() throws error.
    2.1 Connect error: {type: "INVALID_OPERATION", reason: "duplicated operation"}
  3. Video render warning on renderVideo() call.
    3.1 RENDER WARNING: there is no texture bound to the unit 0 ~ 4
    3.2 WebGL: too many errors, no more errors will be reported to the console for this context.
  4. Video doesn’t render on stream.startVideo() and stream.renderVideo() after stream.stopVideo().
    4.1 There’s no warning or error on this stage, camera light is on, but not rendering on canvas.
  5. Not receiving video-active-change for some participants.
    5.1 I am testing it on my local machine only with 3 different browsers, and I am not sure if it is by design, but not every participants receives video-active-change event when some of participants starts video.
    5.2 Because of this, I am having hard time to render the all videos from all participants.

I will keep add more when I find more issues, but hope they all could be fixed soon.


Hey @ktae13 ,

For additional issues, please create new topics and fill out the post template so we have enough info to debug and for easier tracking. :slight_smile:

Here is a possible solution for your original issue:

Since we support rendering multiple videos (gallery view), the video-active-change event is not essential for rendering video. There are two events that you can take into account: peer-video-state-change and user-updated.

client.on('peer-video-state-change',async (payload)=>{
    const { action,userId } = payload;
        render video on canvas 

        we recommend the aspect = 16/9, and please note that the origin of the coordinates is the lower left corner of the canvas.

      await stream.renderVideo(canvas,userId,width,height,x,y,quality);
    }else if(action==='Stop'){
      await stream.stopRenderVideo(canvas,userId);

If you need to display a list of users in pages, we recommend that you maintain a list of rendered videos by yourself. You can render or stop rendering videos when the users in the list change. Listen to the user-updated and user-removed events to update the list of rendered videos.

let renderedList = [];
  let page = 0
  let pageSize = 5;
  const canvas = document.querySelector('.video-canvas');// canvas to render the video
  const handleParticipantsChange = (participants)=>{
    const pageParticipants = participants.filter((user,index)=>Math.floor(index/pageSize)===page);
    const videoParticipants = pageParticipants.filter(user=>user.bVideoOn);
    /** For performance reasons, the SDK can only render 9 videos at the same time, we recommand 
     * to stop rendering the old video and then render a new video
     * **/
    const removedVideoParticipants = renderedList.filter(user=>videoParticipants.findIndex(user2=>user2.userId===user.userId)===-1);
      removedVideoParticipants.forEach(async (user)=>{
        await stream.stopRenderVideo(canvas,user.userId);
    const addedVideoParticipants = videoParticipants.filter(user=>renderedList.findIndex(user2=>user2.userId===user.userId)===-1);
      addedVideoParticipants.forEach(async (user)=>{
        // render new video
      await stream.renderVideo(canvas,user.userId,width,height,x,y,quality);
    renderedList = videoParticipants;
    const participants = client.getParticipantsList();
    const participants = client.getParticipantsList();

For more details please refer to the tutorial and the sample demo project (React). This is a full demo of how to manage multi-user video rendering and paging.

If you have followed the guidance to render video, but there is still no drawing on the canvas, please check whether you have set the width and height attributes of the canvas.


Thanks @tommy ,

Marking it as resolved.

I didn’t know about peer-video-state-change event, since I thought video-active-change handles every video related events. :slight_smile:

I guess I would need to take a look at the sample codes more carefully.

Thank you,

1 Like

Happy to hear that suggestion resolved the issue for you! :slight_smile:

We will be updating the docs to make this more clear.