How do I fix the following issues with my port of a manifest v2 browser extension to manifest v3?

I am in the process of transitioning a manifest v2 Chrome extension to manifest v3 and while converting my background script background.js to a service worker, and I am getting error messages in Google Chrome. I am somewhat familiar with Manifest v3, however the concept of service workers is still very confusing to me. Here is the error message. Note: Keep in mind, despite the single error message, I believe there may be some logical errors rather than syntax errors in my source code that may present undesired or unexpected behavior in the browser extension.

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.

To put this error into context, I have included the code of my service worker called service-worker.js, content-script.js, and manifest.json. I think I did most of the “heavy lifting” porting my MV2 extension to MV3, but there seems to be some minor issues.

service-worker.js

"use strict";

function sendAudioMessage(actionType, audioFile) {
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    tabs.forEach(tab => {
      chrome.tabs.sendMessage(tab.id, { action: actionType });
    });
  });
}

chrome.webNavigation.onCreatedNavigationTarget.addListener(onNav);
chrome.webNavigation.onBeforeNavigate.addListener(onNav);
chrome.webNavigation.onReferenceFragmentUpdated.addListener(onNav);
chrome.webNavigation.onHistoryStateUpdated.addListener(onNav);

function onNav({frameId}) {
  if(frameId > 0) return;
  sendAudioMessage('playNavigationSound');
}

chrome.downloads.onChanged.addListener(delta => {
  if(delta.state && delta.state.current === "complete") {
    sendAudioMessage('playDownloadCompleteSound');
  }
  if(delta.error && delta.error.current) {
    sendAudioMessage('playDownloadErrorSound');
  }
});

chrome.tabs.onUpdated.addListener((tabId, {mutedInfo}) => {
  if(mutedInfo && mutedInfo.reason === "user") {
    sendAudioMessage('playMuteWarningSound'); 
  }
});

function changeVolume(volumeLevel) {
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    tabs.forEach(tab => {
      chrome.tabs.sendMessage(tab.id, { action: 'changeVolume', volume: volumeLevel });
    });
  });
}

// *** Message Handler ***
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  switch (message.action) {
    case 'playNavigationSound':
      sendAudioMessage('playNavigationSound');
      break;
    case 'playDownloadCompleteSound':
      sendAudioMessage('playDownloadCompleteSound');
      break;
    case 'playDownloadErrorSound':
      sendAudioMessage('playDownloadErrorSound');
      break;
    case 'playMuteWarningSound':
      sendAudioMessage('playMuteWarningSound');
      break;
    case 'changeVolume':
      changeVolume(0.75); 
      break;
    default:
      console.log('Unknown message action:', message.action);
  }
});

content-script.js

// Helper function to play audio
function playAudio(audioFile) {
  const audio = new Audio(chrome.runtime.getURL(audioFile)); // Use chrome.runtime.getURL for packaged extension resources
  audio.play();
}

// Helper function for setting volume
function setAudioVolume(volumeLevel) {
  const audioElements = document.querySelectorAll('audio');
  audioElements.forEach(audio => {
      audio.volume = volumeLevel;
  });
}

// Receive messages from your service worker
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  switch (message.action) {
      case 'playNavigationSound':
          playAudio('nav.ogg');
          break;
      case 'playDownloadCompleteSound':
          playAudio('done.ogg');
          break;
      case 'playDownloadErrorSound':
          playAudio('error.ogg');
          break;
      case 'playMuteWarningSound':
          playAudio('unlock.ogg');
          break;
      case 'changeVolme':
          setAudioVolume(0.75);
          break;
      default:
          console.log('Unknown message action:', message.action);
  }
});
  

manifest.json

{
  "manifest_version": 3,
  "name": "PopupSound",
  "description": "Plays a click sound when you click on a link. Also plays a trumpet sound when you finish downloading a file.",
  "author": "Michael Gunter",
  "version": "3.0",
  "default_locale": "en",
  "offline_enabled": true,
  "icons": {
    "32": "icon_32.png",
    "96": "icon_96.png",
    "128": "icon_128.png"
  },
  "background": {
    "service_worker": "service-worker.js"
  },
  "permissions": [
    "webNavigation",
    "downloads",
    "tabs"
  ],

  "content_scripts": [
    {
      "matches": ["<all_urls>"], 
      "js": ["content-script.js"],
      "run_at": "document_start"
    }
  ],

  "content_security_policy": {}
}

Edit: While I no longer get the error message when the extension runs, I now get two error messages when audio is expected to be played from the browser extension.

Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.

Uncaught (in promise) NotAllowedError: play() can only be initiated by a user gesture.

I hope this helps.