javascriptgoogle-chrome-extensionmicrosoft-edgemicrosoft-edge-extension

Chrome extension declarativeNetRequest, updateDynamicRules, id for new rule being added is never unique


I wanna make a chrome/edge extension that whenever a URL request is made (like googling, or entering something like a search or a site into the URL bar), checks whether it contains certain keywords, and blocks the request if it does.

So far all the syntax is correct, but I keep getting an error on the Rule.id property, and I cannot find out why.

(async () => {
  await chrome.declarativeNetRequest.updateDynamicRules(
    // options
    {
        // Rule[]
        addRules: [
            // Rule
            {
                action: {
                    type: "block"
                },
                // RuleCondition
                condition: {
                    // string
                    urlFilter: "*youtube|test1*"
                },
                id: 1
            }
        ]
    }
  );
})();

A "fix" is to remove the parameter parenthes at the end of the async function (because updateDynamicRules() is a promise), but then its not a function so nothing gets executed.

Another thing I've tried, which shows the problem isn't the Rule.id itself, is setting the id as both 1, 2, and twice a random number - every time i get "Error: Rule with id x does not have a unique ID." and error pointer thing pointing at line 22, which btw is where the code ends.


Solution

    1. It may be an old rule from your previous attempts. The API is unergonomic and its developer rejected my idea to simplify it, so the solution is to always remove the old id explicitly:

      await chrome.declarativeNetRequest.updateDynamicRules({
        removeRuleIds: [1],
        addRules: [{ 
          id: 1,
          // .......................
        }],
      });
      
    2. Your urlFilter is invalid. A valid one would be "youtube" or "test1". If you want to match several patterns, you'll have to create several rules, which is more performant usually than the alternative of using a single regexFilter: "youtube|test1".