jumpserver/jumpserver · error · ValueError

{expression} should be a regular expression

Error message

{expression} should be a regular expression

What it means

__match() accepts either a plain string (compiled with DOTALL|IGNORECASE) or a precompiled re.Pattern. Any other type (dict, int, compiled-with-wrong-type, bytes, etc.) raises ValueError.

Source

Thrown at apps/libs/ansible/modules_utils/remote_client.py:858

        if answers is None:
            result = []
        elif isinstance(answers, (str, re.Pattern)):
            result = [answers]
        elif isinstance(answers, (list, tuple)):
            result = list(answers)
        else:
            raise ValueError('Answers must be a regular expression or a list')

        if len(result) < len(commands):
            result.extend([DEFAULT_RE] * (len(commands) - len(result)))
        return result

    @staticmethod
    def __match(expression, content):
        if isinstance(expression, str):
            expression = re.compile(expression, re.DOTALL | re.IGNORECASE)
        elif not isinstance(expression, re.Pattern):
            raise ValueError(f'{expression} should be a regular expression')

        return bool(expression.search(content))

    @staticmethod
    def _channel_is_closed(channel):
        return bool(
            getattr(channel, 'closed', False)
            or getattr(channel, 'eof_received', False)
        )

    @raise_timeout('Recv message')
    def _get_match_recv(
        self,
        answer_reg=DEFAULT_RE,
        allow_quiet=False,
        quiet_period=None,
    ):
        buffer_str = ''

View on GitHub (pinned to 6ec464fabd)

Solutions

  1. Ensure every answer/pattern passed to execute()/switch_user APIs is a str or re.Pattern
  2. Decode bytes patterns to str
  3. Flatten nested lists of answers

Example fix

# before
client.execute(['enable'], answers=[b'Password:'])

# after
client.execute(['enable'], answers=['Password:'])
Defensive patterns

Strategy: validation

Validate before calling

assert all(isinstance(a, (str, re.Pattern)) for a in answers), 'answers must be str or re.Pattern'

Type guard

def is_pattern_like(x) -> bool:
    return isinstance(x, str) or isinstance(x, re.Pattern)

Prevention

When it happens

Trigger: Internal/_get_match_recv callers passing an expression that is not str or re.Pattern — in practice, user-supplied answer regexes that are, e.g., bytes or a list element of wrong type reaching the matcher.

Common situations: Passing bytes regex b'Password:', passing a list as a single answer, or a custom object with __str__ that was never stringified.

Related errors


AI-assisted analysis of jumpserver/jumpserver@6ec464fabd (2026-08-28). Data as JSON: /api/errors/a2c07a5de8abbdff. Report an issue: GitHub.