{"record":{"id":"37498801c0a9e86e","repo":"mongodb/laravel-mongodb","slug":"missing-expected-ending-delimiter-s-in-regular-expression-s","errorCode":null,"errorMessage":"Missing expected ending delimiter \"%s\" in regular expression \"%s\"","messagePattern":"Missing expected ending delimiter \"(.+?)\" in regular expression \"(.+?)\"","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/Query/Builder.php","lineNumber":1516,"sourceCode":"            // 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        }\n\n        if (! isset($operator) || $operator === '=' || $operator === 'eq') {\n            $query = [$column => $value];\n        } else {\n            $query = [$column => ['$' . $operator => $value]];\n        }","sourceCodeStart":1498,"sourceCodeEnd":1534,"githubUrl":"https://github.com/mongodb/laravel-mongodb/blob/0634653039468ceb0268a69192bdac64469ed043/src/Query/Builder.php#L1498-L1534","documentation":"After validating the leading delimiter of a regex where value, the pattern is exploded by the delimiter; fewer than 3 parts means the closing delimiter is missing (e.g. '/^abc'). The library needs the trailing delimiter to separate the pattern body from its flags and throws LogicException otherwise.","triggerScenarios":"->where('name', 'regex', '/^abc') (no closing /); unbalanced delimiters where an escaped delimiter broke the count; patterns like '/ab/' missing the flags segment count due to typos.","commonSituations":"Dynamically-built patterns where the closing delimiter was dropped in string interpolation; hand-written patterns from Mongo shell that omit trailing slash.","solutions":["Close the pattern: ->where('name', 'regex', '/^abc/').","Include flags after the closing delimiter if needed: '/^abc/i'.","Prefer BSON Regex objects: new Regex('^abc', 'i') — no delimiter parsing at all.","Escape inner occurrences of the delimiter (\\/ for '/') so the count stays balanced."],"exampleFix":"// before\n$query->where('name', 'regex', '/^abc');\n// after\n$query->where('name', 'regex', '/^abc/i');","handlingStrategy":"validation","validationCode":"if (is_string($pattern) && substr_count($pattern, substr($pattern, 0, 1)) < 2) {\n    $pattern .= substr($pattern, 0, 1); // close the delimiter\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify the pattern ends with its opening delimiter.","Prefer new Regex($body, $flags) to skip parsing.","Escape embedded delimiters in dynamic patterns."],"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"}