{"record":{"id":"8dfc831981b24ae9","repo":"gildas-lormeau/SingleFile","slug":"url-is-empty","errorCode":null,"errorMessage":"URL is empty","messagePattern":"URL is empty","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bg/config.js","lineNumber":674,"sourceCode":"\nasync function getProfileKeyNames() {\n\treturn Object.keys(await configStorage.get()).filter(key => key.startsWith(PROFILE_NAME_PREFIX));\n}\n\nasync function getProfile(profileName) {\n\tconst profileKey = PROFILE_NAME_PREFIX + profileName;\n\tconst data = await configStorage.get([profileKey]);\n\treturn data[profileKey];\n}\n\nasync function setProfile(profileName, profileData) {\n\tconst profileKey = PROFILE_NAME_PREFIX + profileName;\n\tawait configStorage.set({ [profileKey]: profileData });\n}\n\nasync function addRule(url, profile, autoSaveProfile) {\n\tif (!url) {\n\t\tthrow new Error(\"URL is empty\");\n\t}\n\tconst rules = await getRules();\n\tif (rules.find(rule => rule.url == url)) {\n\t\tthrow new Error(\"URL already exists\");\n\t}\n\trules.push({\n\t\turl,\n\t\tprofile,\n\t\tautoSaveProfile\n\t});\n\tawait configStorage.set({ rules });\n}\n\nasync function deleteRule(url) {\n\tif (!url) {\n\t\tthrow new Error(\"URL is empty\");\n\t}\n\tconst rules = await getRules();","sourceCodeStart":656,"sourceCodeEnd":692,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/core/bg/config.js#L656-L692","documentation":"addRule validates its url argument and throws 'URL is empty' when the value is falsy (undefined, null, or empty string). A rule maps a URL pattern to a profile, so an empty URL would create a meaningless/unmatchable rule. The throw happens before getRules() so storage is never touched.","triggerScenarios":"Calling addRule('', profile, autoSaveProfile) or addRule(undefined, ...) — typically from an options-page form where the URL input was left blank, or from a message handler that dropped the url field.","commonSituations":"Submitting an 'add rule' form without filling the URL field; a messaging bug where the payload key is misspelled so url arrives undefined.","solutions":["Validate the URL input in the UI before calling addRule and show a required-field error.","Trim the input: addRule(url.trim(), ...) and check length > 0 before invoking.","Ensure message senders include the url property (check key spelling in the onMessage payload)."],"exampleFix":"// before\nawait addRule(urlInput.value, profile);\n// after\nconst url = urlInput.value.trim();\nif (!url) throw new Error('URL is required');\nawait addRule(url, profile);","handlingStrategy":"validation","validationCode":"const url = (urlInput.value || '').trim();\nif (!url) throw new Error('URL is required');\nawait addRule(url, profile, autoSaveProfile);","typeGuard":"const isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"try { await addRule(url, profile); } catch (e) { if (e.message === 'URL is empty') showFieldError('url', 'Required'); else throw e; }","preventionTips":["Mark the URL input required in the form","Trim user input before API calls","Verify message payloads include the url key"],"tags":["validation","config","rules"],"backgroundTag":"missing-url","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}