{"record":{"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/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/mark/__init__.py#L265-L301","documentation":"Raised as a UsageError when pytest fails to compile a marker or keyword expression supplied via -m / -k (or the API equivalent). The original SyntaxError from the expression parser is unwrapped and re-thrown with a pytest-level message, prefixing the location-specific details (offending text, column offset, message). It stops collection because pytest cannot decide which tests to select.","triggerScenarios":"Calling pytest with `-m 'not (smoke'` (unbalanced parens), `-k 'test_ and'` (trailing operator), or programmatically invoking deselect_by_mark / deselect_by_keyword with a malformed expression string. Any string that Expression.compile cannot parse triggers it.","commonSituations":"Typos in CLI selection expressions, copy-pasting a partial expression, using shell quoting that strips parentheses, or upgrading pytest where the marker expression grammar changed (e.g. introducing kwargs).","solutions":["Re-run pytest and read the full message: it names the offending text, the 1-based column, and the parser's complaint.","Balance parentheses/quotes in the -m or -k value and quote the whole expression in the shell.","If the expression is built dynamically, validate it with `Expression.compile(expr)` in a try/except before passing it to pytest.","Simplify the expression to a single marker name and re-add operators one at a time to isolate the syntax fault."],"exampleFix":"# before\npytest -m 'not (smoke'\n# after\npytest -m 'not smoke'","handlingStrategy":"validation","validationCode":"from _pytest.mark.expression import Expression\n\ndef safe_marker_expr(expr: str) -> bool:\n    try:\n        Expression.compile(expr)\n        return True\n    except SyntaxError:\n        return False","typeGuard":null,"tryCatchPattern":"from _pytest.config import UsageError\ntry:\n    deselect_by_keyword(items, config)\nexcept UsageError as e:\n    # report the bad expression to the user / fall back to no filter\n    print(f'invalid selection expression: {e}')","preventionTips":["Treat -m/-k values as data, not Python; validate before passing to pytest APIs.","Quote CLI expressions to avoid shell interference.","Build marker expressions from a known-good vocabulary of marker names."],"tags":["pytest","marker-expression","cli","syntax-error","usage-error"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}