title: Failed to execute 'drawImage' on 'CanvasRenderingContext2D'
body: <p>I received the following error:</p>
  
  <blockquote>
    <p>Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'</p>
  </blockquote>
  
  <p>I saw reference to the same error here but the implementation was different from mines.  This is a game and it renders some images but still gives this error.  Here is my code:</p>
  
  <p>This is the line where chrome states the error is:</p>
  
  <pre><code>for (row = 0; row &lt; numRows; row++) {
      for (col = 0; col &lt; numCols; col++) {
          /* The drawImage function of the canvas' context element
           * requires 3 parameters: the image to draw, the x coordinate
           * to start drawing and the y coordinate to start drawing.
           * We're using our Resources helpers to refer to our images
           * so that we get the benefits of caching these images, since
           * we're using them over and over.
           */
           ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83);
          }
  }
  </code></pre>
  
  <p>It's the <code>ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83)</code>.</p>
  
  <p>This is the full function <code>render()</code>. The images are contained in the following array:</p>
  
  <pre><code>function render() {
          /* This array holds the relative URL to the image used
           * for that particular row of the game level.
           */
          var rowImages = [
                  'images/water-block.png',   // Top row is water
                  'images/stone-block.png',   // Row 1 of 3 of stone
                  'images/stone-block.png',   // Row 2 of 3 of stone
                  'images/stone-block.png',   // Row 3 of 3 of stone
                  'images/grass-block.png',   // Row 1 of 2 of grass
                  'images/grass-block.png'    // Row 2 of 2 of grass
              ],
              numRows = 6,
              numCols = 5,
              row, col;
  
          /* Loop through the number of rows and columns we've defined above
           * and, using the rowImages array, draw the correct image for that
           * portion of the "grid"
           */
          for (row = 0; row &lt; numRows; row++) {
              for (col = 0; col &lt; numCols; col++) {
                  /* The drawImage function of the canvas' context element
                   * requires 3 parameters: the image to draw, the x coordinate
                   * to start drawing and the y coordinate to start drawing.
                   * We're using our Resources helpers to refer to our images
                   * so that we get the benefits of caching these images, since
                   * we're using them over and over.
                   */
                   ctx.drawImage(resources.get(rowImages[row]), col * 101, row * 83);
              }
            }
  
  
          renderEntities();
      }  //END RENDER
  </code></pre>
  
  <p>resources is a separate file <code>resources.js</code> that creates a cache for the images, the code follows in case this helps:</p>
  
  <pre><code>(function() {
      var resourceCache = {};
      var loading = [];
      var readyCallbacks = [];
  
      /* This is the publicly accessible image loading function. It accepts
       * an array of strings pointing to image files or a string for a single
       * image. It will then call our private image loading function accordingly.
       */
      function load(urlOrArr) {
          if(urlOrArr instanceof Array) {
              /* If the developer passed in an array of images
               * loop through each value and call our image
               * loader on that image file
               */
              urlOrArr.forEach(function(url) {
                  _load(url);
              });
          } else {
              /* The developer did not pass an array to this function,
               * assume the value is a string and call our image loader
               * directly.
               */
              _load(urlOrArr);
          }
      }
  
      /* This is our private image loader function, it is
       * called by the public image loader function.
       */
      function _load(url) {
          if(resourceCache[url]) {
              /* If this URL has been previously loaded it will exist within
               * our resourceCache array. Just return that image rather than
               * re-loading the image.
               */
              return resourceCache[url];
          } else {
              /* This URL has not been previously loaded and is not present
               * within our cache; we'll need to load this image.
               */
              var img = new Image();
              img.src = url;
              img.onload = function() {
                  /* Once our image has properly loaded, add it to our cache
                   * so that we can simply return this image if the developer
                   * attempts to load this file in the future.
                   */
                  resourceCache[url] = img;
  
                  /* Once the image is actually loaded and properly cached,
                   * call all of the onReady() callbacks we have defined.
                   */
                  if(isReady()) {
                      readyCallbacks.forEach(function(func) { func(); });
                  }
              };
  
              /* Set the initial cache value to false, this will change when
               * the image's onload event handler is called. Finally, point
               * the images src attribute to the passed in URL.
               */
              resourceCache[url] = false;
  
          }
      }
  
        function get(url) {
          return resourceCache[url];
      }
  
      /* This function determines if all of the images that have been requested
       * for loading have in fact been completly loaded.
       */
      function isReady() {
          var ready = true;
          for(var k in resourceCache) {
              if(resourceCache.hasOwnProperty(k) &amp;&amp;
                 !resourceCache[k]) {
                  ready = false;
              }
          }
          return ready;
      }
  
      /* This function will add a function to the callback stack that is called
       * when all requested images are properly loaded.
       */
      function onReady(func) {
          readyCallbacks.push(func);
      }
  
      /* This object defines the publicly accessible functions available to
       * developers by creating a global Resources object.
       */
      window.resources = {
          load: load,
          get: get,
          onReady: onReady,
          isReady: isReady
      };
  })();
  </code></pre>
  
  <p>Chrome also listed two other sections under the same error:</p>
  
  <pre><code>var main = function () {
      var now = Date.now();
      var delta = now - then;
  
      update(delta / 1000);
      render();
  
      then = now;
  
      //Request to do this again ASAP
      requestAnimationFrame(main);
  }
  </code></pre>
  
  <p>The error is on the render call render();</p>
  
  <p>and on the last line of my file which calls main() as follows:</p>
  
  <pre><code>// Let's play this game!
  var then = Date.now();
  reset();
  main();
  </code></pre>