Continuously running into errors with javascript chrome extension, made changes to manifest etc but errors persist

I wrote some code that uses face-api.js to detect and differentiate between male and female faces and then blur out female bodies, meant to be an experimental extension I’m working on that’ll eventually be used for censoring potentially unwanted media.

The code seems to be fine and loads well onto chrome, only repeatedly runs into errors and I don’t know why. I’ve made a contentScript.js file, a manifest.json file, a background.js file, popup.html, popup.css and popup.js file, some icons and a root directory, and gone through all of them repeatedly looking for what is wrong but can’t seem to find a solution. Any ideas?

contentScript.js:

// Load the face detection and gender classification models
Promise.all([
  faceapi.nets.ssdMobilenetv1.loadFromUri('https://cdn.jsdelivr.net/npm/@vladmandic/face-api@latest/weights'),
  faceapi.nets.genderRecognitionNet.loadFromUri('https://cdn.jsdelivr.net/npm/@vladmandic/face-api@latest/weights')
]).then(startVideo)

// Define the canvas element for drawing the boxes
const canvas = document.createElement('canvas')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
canvas.style.position = 'fixed'
canvas.style.top = '0'
canvas.style.left = '0'
canvas.style.pointerEvents = 'none'
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')

// Get the video element
const video = document.querySelector('video')

// Start the video playback and detection loop
async function startVideo() {
  // Play the video
  await video.play()

  // Define the face detection and gender classification options
  const options = new faceapi.SsdMobilenetv1Options({ minConfidence: 0.5 })

  // Define the loop function
  async function detectFacesAndGender() {
    // Detect all faces in the video frame and classify their gender
    const detections = await faceapi.detectAllFaces(video, options).withFaceLandmarks().withGender()

    // Loop through each face and determine its gender
    detections.forEach(async detection => {
      const gender = detection.gender // "male", "female", or "genderless"

      // Determine whether to draw a box around the face or blur the body
      if (gender === "female") {
        // Place a red box around the face
        const box = detection.detection.box
        ctx.beginPath()
        ctx.lineWidth = '6'
        ctx.strokeStyle = 'red'
        ctx.rect(box.x, box.y, box.width, box.height)
        ctx.stroke()

        // Blur female bodies
        const image = await faceapi.bufferToImage(detection.detection._imageData)
        const canvas2 = faceapi.createCanvasFromMedia(image)
        const displaySize = { width: image.width, height: image.height }
        faceapi.matchDimensions(canvas2, displaySize)
        const resizedDetection = faceapi.resizeResults(detection, displaySize)
        const bodyPart = resizedDetection.detection.imageDims !== displaySize ? faceapi.CANVAS : undefined
        const blurAmount = 10
        faceapi.drawDetection(canvas2, resizedDetection, { color: 'rgba(255, 0, 0, 1)' })
        await faceapi.blurFaces(canvas2, [resizedDetection], blurAmount, bodyPart)
        const blurredImage = new Image()
        blurredImage.src = canvas2.toDataURL()
        const parentElement = detection.forSize(canvas.width, canvas.height).parentElement
        let femaleBody = parentElement.querySelector('.female-body')
        if (!femaleBody) {
          const img = document.createElement('img')
          img.classList.add('female-body')
          img.style.position = 'absolute'
          img.style.top = '0'
          img.style.left = '0'
          img.style.width = '100%'
          img.style.height = '100%'
          img.style.objectFit = 'contain'
          parentElement.appendChild(img)
          femaleBody = img
        }
        femaleBody.src = blurredImage.src
      } else if (gender === "male" || gender === "genderless") {
        // Unblur male and genderless bodies
        const parentElement = detection.forSize(canvas.width, canvas.height).parentElement
        const maleOrGenderlessBody
      } else if (gender === "male" || gender === "genderless") {
        // Unblur male and genderless bodies
        const parentElement = detection.forSize(canvas.width, canvas.height).parentElement
        const maleOrGenderlessBody = parentElement.querySelector(".body-male, .body-genderless")
        if (maleOrGenderlessBody) {
          maleOrGenderlessBody.style.filter = "none"
        }
      }

      // Add the modified canvas back to the DOM
      parentElement.appendChild(canvas)
    }
  }

  // Load the models and start the detection process
  Promise.all([
    faceapi.nets.tinyFaceDetector.loadFromUri(modelURI),
    faceapi.nets.faceLandmark68Net.loadFromUri(modelURI),
    faceapi.nets.faceRecognitionNet.loadFromUri(modelURI),
    faceapi.nets.faceExpressionNet.loadFromUri(modelURI),
    faceapi.nets.ageGenderNet.loadFromUri(modelURI),
    faceapi.nets.ssdMobilenetv1.loadFromUri(modelURI)
  ]).then(startDetection)

  // Display a message if an error occurs during detection
  const errorElement = document.getElementById("error-message")
  const displayError = (errorMessage) => {
    errorElement.innerHTML = errorMessage
    errorElement.style.display = "block"
  }
  window.onerror = (message, source, lineno, colno, error) => {
    displayError(`An error occurred: ${message}`)
    return true
  }
  Promise.all([
    faceapi.nets.tinyFaceDetector.loadFromUri(modelURI),
    faceapi.nets.faceLandmark68Net.loadFromUri(modelURI),
    faceapi.nets.faceRecognitionNet.loadFromUri(modelURI),
    faceapi.nets.faceExpressionNet.loadFromUri(modelURI),
    faceapi.nets.ageGenderNet.loadFromUri(modelURI),
    faceapi.nets.ssdMobilenetv1.loadFromUri(modelURI)
  ]).catch((error) => displayError(`There was an error loading the models: ${error}`))
}

manifest.json:

{
  "manifest_version": 3,
  "name": "Image/Video Blur",
  "version": "1.0",
  "description": "An extension to blur images and videos",
  "icons": {
    "16": "icon16.png",
    "32": "icon32.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "permissions": ["activeTab", "scripting", "tabs"],
  "host_permissions": ["*://*/*"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icon16.png",
      "32": "icon32.png",
      "48": "icon48.png",
      "128": "icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["contentScript.js"]
    }
  ]
}

background.js:

chrome.action.onClicked.addListener((tab) => {
  chrome.scripting.executeScript({
    target: {tabId: tab.id},
    files: ['contentScript.js']
  });
});

popup.html:

<!DOCTYPE html>
<html>
  <head>
    <title>My Extension</title>
    <link rel="stylesheet" href="popup.css">
  </head>
  <body>
    <h1>Welcome to my extension!</h1>
    <p>Click the button below to blur the current page.</p>
    <button id="blur-button">Blur Page</button>
    <script src="popup.js"></script>
  </body>
</html>

popup.css:

body {
  font-family: Arial, sans-serif;
  font-size: 16px;
  margin: 0;
  padding: 0;
}

h1 {
  font-size: 24px;
  margin-bottom: 10px;
}

p {
  margin-top: 0;
  margin-bottom: 20px;
}

button {
  padding: 10px 20px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #3e8e41;
}

popup.js:

document.addEventListener('DOMContentLoaded', function() {
  var blurButton = document.getElementById('blur-button');
  blurButton.addEventListener('click', function() {
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      chrome.runtime.sendMessage({action: 'blur'});
    });
  });
});

I keep getting errors on Chrome like:

“Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
Context
popup.html
Stack Trace
popup.html:0 (anonymous function)”

“Uncaught SyntaxError: Unexpected end of input
Context
example.org
Stack Trace
contentScript.js:87 (anonymous function)”

Errors like this repeatedly even after I make amends. Something is wrong I’m not able to tell and my little friend can’t tell either. Let me know if you’ve noticed what’s wrong.