# Buggy code
def visit_image(self, node: Element) -> None:
    olduri = node["uri"]
    # rewrite the URI if the environment knows about it
    if olduri in self.builder.images:
        node["uri"] = posixpath.join(self.builder.imgpath, self.builder.images[olduri])

    if "scale" in node:
        # Try to figure out image height and width.  Docutils does that too,
        # but it tries the final file name, which does not necessarily exist
        # yet at the time the HTML file is written.
        if not ("width" in node and "height" in node):
            size = get_image_size(os.path.join(self.builder.srcdir, olduri))
            if size is None:
                logger.warning(
                    __("Could not obtain image size. :scale: option is ignored."),  # NOQA
                    location=node,
                )
            else:
                if "width" not in node:
                    node["width"] = str(size[0])
                if "height" not in node:
                    node["height"] = str(size[1])

    uri = node["uri"]
    if uri.lower().endswith(("svg", "svgz")):
        atts = {"src": uri}
        if "width" in node:
            atts["width"] = node["width"]
        if "height" in node:
            atts["height"] = node["height"]
        if "scale" in node:
            scale = node["scale"] / 100.0
            if "width" in atts:
                atts["width"] = int(atts["width"]) * scale
            if "height" in atts:
                atts["height"] = int(atts["height"]) * scale
        atts["alt"] = node.get("alt", uri)
        if "align" in node:
            atts["class"] = "align-%s" % node["align"]
        self.body.append(self.emptytag(node, "img", "", **atts))
        return

    super().visit_image(node)


# Traceback (ValueError)
# Sphinx version: 2.4.0
# Python version: 3.7.6 (CPython)
# Docutils version: 0.16 release
# Jinja2 version: 2.11.1
# Last messages:
#   writing output... [ 94%] writing/emoji/curated
#   writing output... [ 94%] writing/emoji/index
#   writing output... [ 95%] writing/gitbook/index
#   writing output... [ 95%] writing/gitbook/intro
#   writing output... [ 96%] writing/latex/index
#   writing output... [ 96%] writing/latex/install
#   writing output... [ 97%] writing/latex/intro
#   writing output... [ 97%] writing/md/index
#   writing output... [ 98%] writing/md/md_github
#   writing output... [ 98%] writing/rst/cheatsheet
# Loaded extensions:
#   sphinx.ext.mathjax (2.4.0) from C:\Users\zas\anaconda3\lib\site-packages\sphinx\ext\mathjax.py
#   sphinxcontrib.applehelp (1.0.2) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\applehelp\__init__.py
#   sphinxcontrib.devhelp (1.0.2) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\devhelp\__init__.py
#   sphinxcontrib.htmlhelp (1.0.3) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\htmlhelp\__init__.py
#   sphinxcontrib.serializinghtml (1.1.4) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\serializinghtml\__init__.py
#   sphinxcontrib.qthelp (1.0.3) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\qthelp\__init__.py
#   alabaster (0.7.12) from C:\Users\zas\anaconda3\lib\site-packages\alabaster\__init__.py
#   sphinxcontrib.wavedrom (unknown version) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\wavedrom.py
#   sphinxcontrib.plantuml (unknown version) from C:\Users\zas\anaconda3\lib\site-packages\sphinxcontrib\plantuml.py
#   recommonmark (0.6.0) from C:\Users\zas\anaconda3\lib\site-packages\recommonmark\__init__.py
#   sphinx.ext.graphviz (2.4.0) from C:\Users\zas\anaconda3\lib\site-packages\sphinx\ext\graphviz.py
#   sphinx.ext.ifconfig (2.4.0) from C:\Users\zas\anaconda3\lib\site-packages\sphinx\ext\ifconfig.py
#   sphinx.ext.todo (2.4.0) from C:\Users\zas\anaconda3\lib\site-packages\sphinx\ext\todo.py
#   sphinx.ext.extlinks (2.4.0) from C:\Users\zas\anaconda3\lib\site-packages\sphinx\ext\extlinks.py
#   sphinx.ext.githubpages (2.4.0) from C:\Users\zas\anaconda3\lib\site-packages\sphinx\ext\githubpages.py
#   sphinxemoji.sphinxemoji (0.1.4) from C:\Users\zas\anaconda3\lib\site-packages\sphinxemoji\sphinxemoji.py
#   sphinx_copybutton (0.2.10) from C:\Users\zas\anaconda3\lib\site-packages\sphinx_copybutton\__init__.py
Traceback (most recent call last):
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\cmd\build.py", line 276, in build_main
app.build(args.force_all, filenames)
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\application.py", line 349, in build
self.builder.build_update()
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\builders\__init__.py", line 299, in build_update
len(to_build))
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\builders\__init__.py", line 361, in build
self.write(docnames, list(updated_docnames), method)
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\builders\__init__.py", line 535, in write
self._write_serial(sorted(docnames))
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\builders\__init__.py", line 545, in _write_serial
self.write_doc(docname, doctree)
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\builders\html.py", line 612, in write_doc
self.docwriter.write(doctree, destination)
File "C:\Users\zas\anaconda3\lib\site-packages\docutils\writers\__init__.py", line 78, in write
self.translate()
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\writers\html.py", line 58, in translate
self.document.walkabout(visitor)
File "C:\Users\zas\anaconda3\lib\site-packages\docutils\nodes.py", line 214, in walkabout
if child.walkabout(visitor):
File "C:\Users\zas\anaconda3\lib\site-packages\docutils\nodes.py", line 214, in walkabout
if child.walkabout(visitor):
File "C:\Users\zas\anaconda3\lib\site-packages\docutils\nodes.py", line 214, in walkabout
if child.walkabout(visitor):
[Previous line repeated 3 more times]
File "C:\Users\zas\anaconda3\lib\site-packages\docutils\nodes.py", line 206, in walkabout
visitor.dispatch_visit(self)
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\util\docutils.py", line 484, in dispatch_visit
return method(node)
File "C:\Users\zas\anaconda3\lib\site-packages\sphinx\writers\html5.py", line 548, in visit_image
atts['width'] = int(atts['width']) * scale
ValueError: invalid literal for int() with base 10: '100px'

# Fixed code
def visit_image(self, node: Element) -> None:
    olduri = node["uri"]
    # rewrite the URI if the environment knows about it
    if olduri in self.builder.images:
        node["uri"] = posixpath.join(self.builder.imgpath, self.builder.images[olduri])

    if "scale" in node:
        # Try to figure out image height and width.  Docutils does that too,
        # but it tries the final file name, which does not necessarily exist
        # yet at the time the HTML file is written.
        if not ("width" in node and "height" in node):
            size = get_image_size(os.path.join(self.builder.srcdir, olduri))
            if size is None:
                logger.warning(
                    __("Could not obtain image size. :scale: option is ignored."),  # NOQA
                    location=node,
                )
            else:
                if "width" not in node:
                    node["width"] = str(size[0])
                if "height" not in node:
                    node["height"] = str(size[1])

    uri = node["uri"]
    if uri.lower().endswith(("svg", "svgz")):
        atts = {"src": uri}
        if "width" in node:
            atts["width"] = node["width"]
        if "height" in node:
            atts["height"] = node["height"]
        if "scale" in node:
            if "width" in atts:
                atts["width"] = multiply_length(atts["width"], node["scale"])
            if "height" in atts:
                atts["height"] = multiply_length(atts["height"], node["scale"])
        atts["alt"] = node.get("alt", uri)
        if "align" in node:
            atts["class"] = "align-%s" % node["align"]
        self.body.append(self.emptytag(node, "img", "", **atts))
        return

    super().visit_image(node)