{"record":{"id":"118642aca0113312","repo":"remix-run/remix","slug":"invalid-bypass-pattern-json-stringify-pattern-118642","errorCode":null,"errorMessage":"invalid bypass pattern ${JSON.stringify(pattern)}: empty path segments are not allowed","messagePattern":"invalid bypass pattern (.+?): empty path segments are not allowed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cop-middleware/src/lib/cop.ts","lineNumber":271,"sourceCode":"\n  let matchesSubtree = pathname.endsWith('/')\n  let normalizedPathname =\n    pathname.length > 1 && matchesSubtree ? pathname.slice(0, pathname.length - 1) : pathname\n  let rawSegments = normalizedPathname === '/' ? [] : normalizedPathname.slice(1).split('/')\n  let segments = rawSegments.map((segment, index) =>\n    parseBypassSegment(pattern, segment, index === rawSegments.length - 1),\n  )\n\n  return { method, pathname, segments, matchesSubtree }\n}\n\nfunction parseBypassSegment(\n  pattern: string,\n  segment: string,\n  isLastSegment: boolean,\n): BypassSegment {\n  if (segment === '') {\n    throw new Error(\n      `invalid bypass pattern ${JSON.stringify(pattern)}: empty path segments are not allowed`,\n    )\n  }\n\n  if (!segment.startsWith('{') || !segment.endsWith('}')) {\n    return { type: 'static', value: segment }\n  }\n\n  let wildcardName = segment.slice(1, segment.length - 1)\n  if (wildcardName === '') {\n    throw new Error(\n      `invalid bypass pattern ${JSON.stringify(pattern)}: empty wildcards are not allowed`,\n    )\n  }\n\n  if (wildcardName === '$') {\n    throw new Error(\n      `invalid bypass pattern ${JSON.stringify(pattern)}: \"{$}\" is not supported in cop-middleware`,","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/cop-middleware/src/lib/cop.ts#L253-L289","documentation":"parseBypassSegment throws when a path segment in a bypass pattern is empty, i.e. the pattern contains '//' or a trailing construction that yields an empty segment. Every segment between slashes must be a static value or a {wildcard}. Empty segments usually indicate a typo like a doubled slash.","triggerScenarios":"addInsecureBypassPattern('/admin//users') (double slash), or patterns where splitting the normalized pathname on '/' produces an empty component.","commonSituations":"Typos with doubled slashes; string concatenation building patterns that accidentally inserts an extra '/', e.g. `/admin/ + '/users'`.","solutions":["Remove the double slash: '/admin/users' instead of '/admin//users'","When concatenating pattern strings, normalize with a join that collapses duplicate slashes"],"exampleFix":"// before\nconst base = '/admin/'\ncop.addInsecureBypassPattern(base + '/users') // '/admin//users'\n// after\nconst base = '/admin'\ncop.addInsecureBypassPattern(base + '/users')","handlingStrategy":"validation","validationCode":"function hasNoEmptySegments(pattern: string): boolean {\n  const path = pattern.slice(pattern.indexOf('/'))\n  return !path.split('/').slice(1).some((s, i, arr) => s === '' && i < arr.length - 1)\n}","typeGuard":"const isSegmented = (p: string) => { const parts = p.split('/'); return parts.every((s) => s !== '') }","tryCatchPattern":null,"preventionTips":["Avoid naive string concatenation of pattern fragments","Lint bypass configs for '//' in tests"],"tags":["cop-middleware","bypass-pattern","path-segment","validation"],"backgroundTag":"invalid-path-pattern","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}