rectorphp/rector · error · InvalidEregException
"-" is invalid for the start character in the brackets
Error message
"-" is invalid for the start character in the brackets
What it means
Inside processSquareBracket(), a '-' was consumed as a class member at a position where it is not the first character and is not immediately followed by ']' — i.e. it is neither a leading/trailing literal dash nor the start of a valid range, which POSIX ERE rejects (EregToPcreTransformer.php:216). The InvalidEregException with message '"-" is invalid for the start character in the brackets' aborts the conversion.
Source
Thrown at rules/Php70/EregToPcreTransformer.php:216
}
// retype
$i = (int) $i;
return $i;
}
/**
* @return float[]|int[]|string[]
*/
private function processSquareBracket(string $s, int $i, int $l, string $cls, bool $start): array
{
do {
if ($s[$i] === '[' && $i + 1 < $l && strpos('.=:', $s[$i + 1]) !== \false) {
/** @var string $cls */
[$cls, $i] = $this->processCharacterClass($s, $i, $cls);
} else {
$a = $s[$i];
++$i;
if ($a === '-' && !$start && ($i >= $l || $s[$i] !== ']')) {
throw new InvalidEregException('"-" is invalid for the start character in the brackets');
}
if ($i < $l && $s[$i] === '-') {
$b = $s[++$i];
if ($b === ']') {
$cls .= $this->_ere2pcre_escape($a) . '\-';
break;
}
if (ord($a) > ord($b)) {
$errorMessage = sprintf('an invalid character range %d-%d"', (int) $a, (int) $b);
throw new InvalidEregException($errorMessage);
}
$cls .= $this->_ere2pcre_escape($a) . '-' . $this->_ere2pcre_escape($b);
++$i;
} else {
$cls .= $this->_ere2pcre_escape($a);
}
}
$start = \false;View on GitHub (pinned to 408fcb0ff1)
Solutions
- Rewrite the class in the flagged file so '-' is a range start, range end, or escaped/edge literal: '[0-9-x]' -> '[0-9x]' or '[0-9\-x]'.
- If the dash is literal, move it to the end ('[0-9x-]') or escape it ('[0-9\-x]').
- Re-run rector; preflight literal ereg patterns for '-' not adjacent to '[' or ']' inside classes.
Example fix
// before - '-' at atom position inside class
ereg('[0-9-x]', $subject);
// after - dash handled explicitly
ereg('[0-9x-]', $subject); // rector: preg_match('#[0-9x-]#m', $subject) Defensive patterns
Strategy: try-catch
Validate before calling
// quick lint: '-' mid-class not adjacent to '[' or ']'
function dashMisplacedInClass(string $p): bool {
return (bool) preg_match('~(?<!^)(?<!\[)-(?![\]\\])~', $p);
} Try / catch
try {
$pcre = $eregToPcreTransformer->transform($pattern, $ignoreCase);
} catch (InvalidEregException $e) {
// '-' used where a class member must start — move it to the class edge or escape it
continue;
} Prevention
- Put literal dashes at the very start or end of a class ('[-a]', '[a-]') or escape them ('\-').
- When appending to an existing range class, re-check where '-' lands: '[0-9-x]' is invalid, '[0-9x-]' is not.
- Review character classes once before the migration instead of per-rector-run.
When it happens
Trigger: Rector (Php70 set / EregToPregMatchRector, target PHP >= 7.0) visits an ereg-family call whose literal pattern has a '-' mid-class where a character should start, e.g. `ereg('[0-9-x]', $s)` (after the range 0-9, '-' is followed by 'x', not ']'), or `split('[abc-', $s)` style content where '-' precedes a non-']' character at class end. Note '[a-]' and '[-a]' are accepted; '[ab-9]' is not.
Common situations: Character classes edited by appending '-x' to an existing range ('[0-9]' -> '[0-9-x]') which silently changes '-' into an atom position; glob/habit thinking where '-' separates members; legacy patterns that relied on lenient behavior of other engines.
Related errors
- "[" does not have a matching "]"
- an invalid character range %d-%d"
- an invalid or unsupported character class [%s]
- unescaped metacharacter ")"
- unescaped metacharacter "%s"
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/2b27e360ab3ec8f4.
Report an issue: GitHub.