pytest-dev/pytest · error · TypeError

{param} parameter needs to be a string, but {g} given

Error message

{param} parameter needs to be a string, but {g} given

What it means

Raised by `_check_record_param_type` (used by the `record_testsuite_property` fixture) when the property NAME passed in is not a string. The JUnit XML property name must be a string; passing an int/None/etc. triggers TypeError naming the parameter ("name") and the actual type. Note the explicit check runs in the no-xml branch; with --junitxml the underlying recorder applies its own conversion.

Source

Thrown at src/_pytest/junitxml.py:337

        pass

    attr_func = add_attr_noop

    xml = request.config.stash.get(xml_key, None)
    if xml is not None:
        node_reporter = xml.node_reporter(request.node.nodeid)
        attr_func = node_reporter.add_attribute

    return attr_func


def _check_record_param_type(param: str, v: str) -> None:
    """Used by record_testsuite_property to check that the given parameter name is of the proper
    type."""
    __tracebackhide__ = True
    if not isinstance(v, str):
        msg = "{param} parameter needs to be a string, but {g} given"  # type: ignore[unreachable]
        raise TypeError(msg.format(param=param, g=type(v).__name__))


@pytest.fixture(scope="session")
def record_testsuite_property(request: FixtureRequest) -> Callable[[str, object], None]:
    """Record a new ``<property>`` tag as child of the root ``<testsuite>``.

    This is suitable to writing global information regarding the entire test
    suite, and is compatible with ``xunit2`` JUnit family.

    This is a ``session``-scoped fixture which is called with ``(name, value)``. Example:

    .. code-block:: python

        def test_foo(record_testsuite_property):
            record_testsuite_property("ARCH", "PPC")
            record_testsuite_property("STORAGE_TYPE", "CEPH")

    :param name:

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Coerce the name to str before calling: `record_testsuite_property(str(name), value)`.
  2. Validate the name is a non-empty string before recording.
  3. Use string literals or f-strings for property names.

Example fix

// before
record_testsuite_property(count, "v")  # count is int -> TypeError
// after
record_testsuite_property(str(count), "v")
Defensive patterns

Strategy: type-guard

Validate before calling

def safe_record_property(record, name, value):
    if not isinstance(name, str):
        name = str(name)
    record(name, value)

Type guard

def is_valid_property_name(name) -> bool:
    return isinstance(name, str) and len(name) > 0

Prevention

When it happens

Trigger: Calling `record_testsuite_property(123, "v")` or `record_testsuite_property(None, "v")` from a test, where the first argument (name) is not a `str`.

Common situations: Programmatically building property names from computed values (ints/enums) without str() conversion. Passing a variable that is unexpectedly None.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/1a2db5149e9289dc.json. Report an issue: GitHub.