{"id":"871351ccf4f92d5d","repo":"pytest-dev/pytest","slug":"exc-message-e-text-at-column-e-offset-e","errorCode":null,"errorMessage":"{exc_message}: {e.text}: at column {e.offset}: {e.msg}","messagePattern":"(.+?): (.+?): at column (.+?): (.+?)","errorType":"exception","errorClass":"UsageError","httpStatus":null,"severity":"error","filePath":"src/_pytest/mark/__init__.py","lineNumber":283,"sourceCode":"\n    expr = _parse_expression(matchexpr, \"Wrong expression passed to '-m'\")\n    remaining: list[Item] = []\n    deselected: list[Item] = []\n    for item in items:\n        if expr.evaluate(MarkMatcher.from_markers(item.iter_markers())):\n            remaining.append(item)\n        else:\n            deselected.append(item)\n    if deselected:\n        config.hook.pytest_deselected(items=deselected)\n        items[:] = remaining\n\n\ndef _parse_expression(expr: str, exc_message: str) -> Expression:\n    try:\n        return Expression.compile(expr)\n    except SyntaxError as e:\n        raise UsageError(\n            f\"{exc_message}: {e.text}: at column {e.offset}: {e.msg}\"\n        ) from None\n\n\ndef pytest_collection_modifyitems(items: list[Item], config: Config) -> None:\n    deselect_by_keyword(items, config)\n    deselect_by_mark(items, config)\n\n\ndef pytest_configure(config: Config) -> None:\n    config.stash[old_mark_config_key] = MARK_GEN._config\n    MARK_GEN._config = config\n\n    # Eagerly validate the value; it is only read lazily during collection.\n    config.getini(EMPTY_PARAMETERSET_OPTION)\n\n\ndef pytest_unconfigure(config: Config) -> None:","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/mark/__init__.py#L265-L301","documentation":"This is pytest's top-level wrapper that converts a SyntaxError raised while compiling a `-k`/`-m` match expression into a UsageError. The `exc_message` prefix (e.g. \"Wrong expression passed to '-m' option\") tells you which CLI flag caused it; the rest reports the offending text, 1-based column, and the underlying parser message. It fires at collection time, before any test runs.","triggerScenarios":"Passing a syntactically invalid string to `pytest -k <expr>`, `pytest -m <expr>`, or to `deselect_by_mark`/`deselect_by_keyword` indirectly. Any SyntaxError emitted by `Expression.compile()` (scanner or parser) gets rewrapped here with the flag-specific prefix.","commonSituations":"Typing a marker filter on the command line with stray characters, unmatched parens, or quoting issues inside the shell; CI configs that interpolate a variable into `-m \"$MARKS\"` that expands to garbage; upgrading pytest and using new kwarg syntax in `-m` incorrectly.","solutions":["Read the column number in the message; it points at the exact offending character in your `-m`/`-k` value.","Quote the whole expression on the shell so spaces/operators are preserved, e.g. `pytest -m 'not slow'`.","Refer to the marker-expression grammar (and/orand/not/ident/kwargs) and simplify the expression until it parses.","If the expression comes from a variable, print it before invocation to verify it is what you expect."],"exampleFix":"# before\npytest -m slow and( integration or slow )\n# after\npytest -m 'slow and (integration or slow)'","handlingStrategy":"validation","validationCode":"from _pytest.mark.expression import Expression\n\ndef validate_marker_expr(expr: str) -> None:\n    Expression.compile(expr)  # raises SyntaxError before pytest runs","typeGuard":"def is_valid_expr(expr: object) -> bool:\n    if not isinstance(expr, str) or not expr.strip():\n        return False\n    try:\n        Expression.compile(expr)\n    except SyntaxError:\n        return False\n    return True","tryCatchPattern":"from _pytest.config import UsageError\n\ntry:\n    pytest.main(['-m', user_expr, *tests])\nexcept UsageError as e:\n    print(f'Bad -m expression: {e}')","preventionTips":["Always quote `-m`/`-k` arguments on the shell.","Validate the expression string in CI config before invoking pytest.","Keep marker expressions simple; prefer multiple `-m` flags over complex boolean expressions."],"tags":["pytest","marker-expression","cli","usage-error"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}