{"id":"a6fbf206758619ee","repo":"pytest-dev/pytest","slug":"str-e-maybe-you-meant-pytest-mark-skipif","errorCode":null,"errorMessage":"{str(e)} - maybe you meant pytest.mark.skipif?","messagePattern":"(.+?) - maybe you meant pytest\\.mark\\.skipif\\?","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/skipping.py","lineNumber":192,"sourceCode":"        else:\n            conditions = (mark.kwargs[\"condition\"],)\n\n        # Unconditional.\n        if not conditions:\n            reason = mark.kwargs.get(\"reason\", \"\")\n            return Skip(reason)\n\n        # If any of the conditions are true.\n        for condition in conditions:\n            result, reason = evaluate_condition(item, mark, condition)\n            if result:\n                return Skip(reason)\n\n    for mark in item.iter_markers(name=\"skip\"):\n        try:\n            return Skip(*mark.args, **mark.kwargs)\n        except TypeError as e:\n            raise TypeError(str(e) + \" - maybe you meant pytest.mark.skipif?\") from None\n\n    return None\n\n\n@dataclasses.dataclass(frozen=True)\nclass Xfail:\n    \"\"\"The result of evaluate_xfail_marks().\"\"\"\n\n    __slots__ = (\"raises\", \"reason\", \"run\", \"strict\")\n\n    reason: str\n    run: bool\n    strict: bool\n    raises: (\n        type[BaseException]\n        | tuple[type[BaseException], ...]\n        | AbstractRaises[BaseException]\n        | None","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/skipping.py#L174-L210","documentation":"Raised when @pytest.mark.skip is applied with arguments that the Skip dataclass cannot accept, almost always because the author meant @pytest.mark.skipif. skip's dataclass (reason, allow_module_level) does not take a positional condition, so Skip(*mark.args, **mark.kwargs) raises TypeError, which pytest re-raises with a helpful suffix suggesting skipif.","triggerScenarios":"Writing @pytest.mark.skip(sys.platform == 'win32') or @pytest.mark.skip(condition) at the top of a test. The TypeError fires during mark evaluation at collection/run time when evaluate_skip_marks tries to construct Skip from the bad mark.","commonSituations":"Copy-pasting from skipif examples without changing the marker name; coming from unittest.skip (which does accept a condition / reason string) and assuming pytest's skip mirrors it; conditional skip intent but unconditional-skip syntax.","solutions":["Use @pytest.mark.skipif(condition, reason=...) for conditional skipping.","For unconditional skip, use @pytest.mark.skip with no args, or @pytest.mark.skip(reason='...').","If you need module-level skipping, use pytestmark = pytest.mark.skip or skip(allow_module_level=True)."],"exampleFix":"// before\n@pytest.mark.skip(sys.platform == \"win32\")\ndef test_windows_only(): ...\n\n// after\n@pytest.mark.skipif(sys.platform == \"win32\", reason=\"windows only\")\ndef test_windows_only(): ...","handlingStrategy":"validation","validationCode":"import inspect, pytest\n\ndef assert_skip_marks_valid(module):\n    for _, obj in inspect.getmembers(module, inspect.isfunction):\n        for mark in getattr(obj, \"pytestmark\", []):\n            if mark.name == \"skip\" and mark.args:\n                raise TypeError(f\"{obj.__name__}: skip with positional args; use skipif\")","typeGuard":"import pytest\n\ndef is_unconditional_skip(mark: pytest.Mark) -> bool:\n    return mark.name == \"skip\" and not mark.args","tryCatchPattern":null,"preventionTips":["Reserve @pytest.mark.skip for unconditional skips (optionally with reason=).","Use @pytest.mark.skipif for any condition-based skip.","Lint in CI: grep for 'mark.skip(' followed by something other than 'reason='."],"tags":["marks","skip","skipif","user-error"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}