{"record":{"id":"4e3eb26ca3b8b21f","repo":"mongodb/laravel-mongodb","slug":"missing-expected-starting-delimiter-in-regular-expression-s","errorCode":null,"errorMessage":"Missing expected starting delimiter in regular expression \"%s\", supported delimiters are: %s","messagePattern":"Missing expected starting delimiter in regular expression \"(.+?)\", supported delimiters are: (.+?)","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/Query/Builder.php","lineNumber":1510,"sourceCode":"                // All backslashes are converted to \\\\, which are needed in matching regexes.\n                preg_quote($value),\n            );\n            $flags = $where['caseSensitive'] ?? false ? '' : 'i';\n            $value = new Regex('^' . $regex . '$', $flags);\n\n            // For inverse like operations, we can just use the $not operator with the Regex\n            $operator = $operator === 'like' ? '=' : 'not';\n            // phpcs:ignore Squiz.ControlStructures.ControlSignature.SpaceAfterCloseBrace\n        }\n\n        // Manipulate regex operations.\n        elseif (in_array($operator, ['regex', 'not regex'])) {\n            // Automatically convert regular expression strings to Regex objects.\n            if (is_string($value)) {\n                // Detect the delimiter and validate the preg pattern\n                $delimiter = substr($value, 0, 1);\n                if (! in_array($delimiter, self::REGEX_DELIMITERS)) {\n                    throw new LogicException(sprintf('Missing expected starting delimiter in regular expression \"%s\", supported delimiters are: %s', $value, implode(' ', self::REGEX_DELIMITERS)));\n                }\n\n                $e = explode($delimiter, $value);\n                // We don't try to detect if the last delimiter is escaped. This would be an invalid regex.\n                if (count($e) < 3) {\n                    throw new LogicException(sprintf('Missing expected ending delimiter \"%s\" in regular expression \"%s\"', $delimiter, $value));\n                }\n\n                // Flags are after the last delimiter\n                $flags = end($e);\n                // Extract the regex string between the delimiters\n                $regstr = substr($value, 1, -1 - strlen($flags));\n                $value = new Regex($regstr, $flags);\n            }\n\n            // For inverse regex operations, we can just use the $not operator with the Regex\n            $operator = $operator === 'regex' ? '=' : 'not';\n        }","sourceCodeStart":1492,"sourceCodeEnd":1528,"githubUrl":"https://github.com/mongodb/laravel-mongodb/blob/0634653039468ceb0268a69192bdac64469ed043/src/Query/Builder.php#L1492-L1528","documentation":"When compiling a 'regex'/'not regex' where clause, a string pattern must be a preg-style pattern with a leading delimiter (e.g. /pattern/i). The library checks the first character against its supported delimiter list and throws LogicException if it isn't one, because it cannot parse flags or the pattern body otherwise.","triggerScenarios":"->where('name', 'regex', '^abc$') (no / delimiters); passing a Mongo shell-style BSON regex string without delimiters; building the regex from concatenation that loses the leading delimiter; REGEX_DELIMITERS mismatch such as using # or unsupported chars.","commonSituations":"Copy-pasting patterns from Mongo shell or regex101 (which use bare patterns or different delimiters); user-supplied search strings wrapped in code not delimiters.","solutions":["Wrap the pattern in delimiters: ->where('name', 'regex', '/^abc$/i').","Choose a supported delimiter character as the first char (e.g. / or ~) matching self::REGEX_DELIMITERS.","If the value may already contain delimiters, detect and only wrap when substr($pattern, 0, 1) is not a delimiter.","Precompile to a MongoDB\\BSON\\Regex object to bypass string parsing: ->where('name', 'regex', new Regex('^abc$', 'i'))."],"exampleFix":"// before\n$query->where('name', 'regex', '^abc');\n// after\n$query->where('name', 'regex', '/^abc/i');","handlingStrategy":"validation","validationCode":"if (is_string($pattern) && !in_array(substr($pattern, 0, 1), ['/', '#', '~'], true)) {\n    $pattern = '/' . trim($pattern, '/') . '/';\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always wrap user patterns in delimiters.","Prefer BSON Regex objects over strings.","Centralize regex-where construction in one helper."],"tags":["php","laravel-mongodb","regex"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"0634653039468ceb0268a69192bdac64469ed043","analyzedAt":"2026-09-15T02:56:37.067Z","contentChangedAt":"2026-09-15T02:56:37.067Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}