{"record":{"id":"0386ce194ddf069c","repo":"pytest-dev/pytest","slug":"e-maybe-you-meant-pytest-mark-skipif","errorCode":null,"errorMessage":"{e} - maybe you meant pytest.mark.skipif?","messagePattern":"(.+?) - maybe you meant pytest\\.mark\\.skipif\\?","errorType":"exception","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/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/skipping.py#L174-L210","documentation":"pytest.mark.skip accepts only reason= and allow_module_level=; it does not take a condition. evaluate_skip_marks() constructs Skip(*mark.args, **mark.kwargs), so passing positional condition arguments (the skipif signature) makes Skip()'s dataclass constructor raise TypeError. pytest catches that TypeError and re-raises it with a hint pointing to skipif, since the most common cause is confusing the two decorators.","triggerScenarios":"Writing @pytest.mark.skip(sys.platform == 'win32', reason='windows-only') or @pytest.mark.skip('some condition') — i.e. giving skip the positional args that belong to skipif. Also triggered by passing an unexpected kwarg to skip.","commonSituations":"Copy-pasting a skipif example and changing the decorator name to skip; reading docs for skipif and applying them to skip; migrating a conditional skip written as `if cond: pytest.skip()` into a decorator form and getting the marker wrong.","solutions":["Switch the decorator to pytest.mark.skipif for conditional skipping: @pytest.mark.skipif(sys.platform == 'win32', reason='...').","If you want unconditional skip, drop the condition arg: @pytest.mark.skip(reason='...').","Pass reason only as a keyword: @pytest.mark.skip(reason='why') — never positional condition args."],"exampleFix":"# before\n@pytest.mark.skip(sys.platform == \"win32\", reason=\"windows-only\")\ndef test_x(): ...\n\n# after\n@pytest.mark.skipif(sys.platform == \"win32\", reason=\"windows-only\")\ndef test_x(): ...","handlingStrategy":"validation","validationCode":"# In conftest.py — collect-time check that surfaces the misuse early.\nimport pytest\n\ndef pytest_collectstart(collector):\n    # Inspect skip marks for positional args (the skipif signature).\n    for mark in getattr(collector, \"iter_markers\", lambda **k: [])() or []:\n        if getattr(mark, \"name\", None) == \"skip\" and mark.args:\n            raise pytest.UsageError(\n                \"pytest.mark.skip got positional args; did you mean skipif?\"\n            )","typeGuard":"# Detect the misuse statically in a lint/check script:\nimport ast\n\ndef skip_has_positional_args(decorator: ast.AST) -> bool:\n    return (\n        isinstance(decorator, ast.Call)\n        and isinstance(decorator.func, ast.Attribute)\n        and decorator.func.attr == \"skip\"\n        and len(decorator.args) >= 1\n    )","tryCatchPattern":"# Not recommended to catch — fix the decorator. If migrating many tests:\nimport re, pathlib\nfor p in pathlib.Path(\"tests\").rglob(\"*.py\"):\n    t = p.read_text()\n    t2 = re.sub(r\"@pytest\\.mark\\.skip\\(([^)]+),\\s*reason=\", r\"@pytest.mark.skipif(\\1, reason=\", t)\n    p.write_text(t2)","preventionTips":["Use skipif for conditional skipping; reserve skip for unconditional skips with only reason=.","Always pass reason as a keyword argument to skip.","Search the codebase for `mark.skip(` with a comma to find existing misuses."],"tags":["markers","skip","skipif","user-error"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}