{"record":{"id":"b16e553e57f01996","repo":"GoogleChrome/lighthouse","slug":"pattern-should-either-be-empty-start-with-or","errorCode":null,"errorMessage":"Pattern should either be empty, start with \"/\" or \"*\"","messagePattern":"Pattern should either be empty, start with \"/\" or \"\\*\"","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"core/audits/seo/robots-txt.js","lineNumber":94,"sourceCode":"\n    try {\n      sitemapUrl = new URL(directiveValue);\n    } catch (e) {\n      throw new Error('Invalid sitemap URL');\n    }\n\n    if (!SITEMAP_VALID_PROTOCOLS.has(sitemapUrl.protocol)) {\n      throw new Error('Invalid sitemap URL protocol');\n    }\n  }\n\n  if (directiveName === DIRECTIVE_USER_AGENT && !directiveValue) {\n    throw new Error('No user-agent specified');\n  }\n\n  if (directiveName === DIRECTIVE_ALLOW || directiveName === DIRECTIVE_DISALLOW) {\n    if (directiveValue !== '' && directiveValue[0] !== '/' && directiveValue[0] !== '*') {\n      throw new Error('Pattern should either be empty, start with \"/\" or \"*\"');\n    }\n\n    const dollarIndex = directiveValue.indexOf('$');\n\n    if (dollarIndex !== -1 && dollarIndex !== directiveValue.length - 1) {\n      throw new Error('\"$\" should only be used at the end of the pattern');\n    }\n  }\n}\n\n/**\n * @param {string} line single line from a robots.txt file\n * @throws will throw an exception if given line has errors\n * @return {{directive: string, value: string}|null}\n */\nfunction parseLine(line) {\n  const hashIndex = line.indexOf('#');\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/audits/seo/robots-txt.js#L76-L112","documentation":"Thrown by verifyDirective() when an Allow or Disallow directive has a pattern value that is non-empty and does not start with '/' or '*'. The robots exclusion standard requires path patterns to be rooted at '/' (absolute path) or use '*' as a wildcard anchor. This enforces syntactic correctness so crawlers can reliably interpret crawl rules.","triggerScenarios":"A robots.txt line like 'Disallow: private' (no leading slash), 'Disallow: ?id=5' (starts with '?'), or 'Allow: .jpg$' (starts with '.'). Any Allow/Disallow value whose first character is not '/', '*', or empty triggers it.","commonSituations":"Developer writes a relative-style path instead of an absolute server path. Copying URL patterns from .htaccess or nginx configs that use different anchoring conventions. Forgetting that robots.txt patterns are path-based, not regex-based.","solutions":["Prefix the pattern with '/', e.g. 'Disallow: /private'","If a wildcard is intended, prefix with '*', e.g. 'Disallow: /*?id='","If you want to allow/disallow everything, use '/' or '*' accordingly"],"exampleFix":"// before\nDisallow: private\n\n// after\nDisallow: /private","handlingStrategy":"validation","validationCode":"// Validate Allow/Disallow patterns before parsing\nfunction validatePatterns(content) {\n  const lines = content.split(/\\r\\n|\\r|\\n/);\n  const errors = [];\n  lines.forEach((line, idx) => {\n    const trimmed = line.split('#')[0].trim();\n    const match = /^(allow|disallow)\\s*:\\s*(.*)$/i.exec(trimmed);\n    if (match && match[2] !== '' && match[2][0] !== '/' && match[2][0] !== '*') {\n      errors.push(`Line ${idx + 1}: Pattern must start with '/' or '*'`);\n    }\n  });\n  return errors;\n}","typeGuard":null,"tryCatchPattern":"try {\n  parseLine(line);\n} catch (e) {\n  // e.message === 'Pattern should either be empty, start with \"/\" or \"*\"'\n  robotsErrors.push({ line, message: e.message });\n}","preventionTips":["Always prefix Allow/Disallow paths with '/' for absolute paths","Use '*' only for wildcard matching at the start of patterns","Test robots.txt rules with Google's robots.txt Tester in Search Console"],"tags":["robots-txt","seo","validation","parsing"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}