{"id":"2133f0899c85c62d","repo":"sqlalchemy/alembic","slug":"don-t-know-how-to-comma-format-r","errorCode":null,"errorMessage":"Don't know how to comma-format %r","messagePattern":"Don't know how to comma-format %r","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"alembic/util/messaging.py","lineNumber":120,"sourceCode":"            subsequent_indent=indent,\n        )\n        if len(lines) > 1:\n            for line in lines[0:-1]:\n                write_outstream(sys.stdout, line, \"\\n\")\n        write_outstream(sys.stdout, lines[-1], (\"\\n\" if newline else \"\"))\n    if flush:\n        sys.stdout.flush()\n\n\ndef format_as_comma(value: str | Iterable[str] | None) -> str:\n    if value is None:\n        return \"\"\n    elif isinstance(value, str):\n        return value\n    elif isinstance(value, Iterable):\n        return \", \".join(value)\n    else:\n        raise ValueError(\"Don't know how to comma-format %r\" % value)\n","sourceCodeStart":102,"sourceCodeEnd":121,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/44fb3450330204b222ff05135e1fbbbdb28c44db/alembic/util/messaging.py#L102-L121","documentation":"Raised as ValueError by format_as_comma (messaging.py:120) when the value is not None, not a str, and not an Iterable — the three cases the helper knows how to render as a comma-separated string. Any other type (int, bool, object) is rejected because the function cannot meaningfully stringify it into the expected 'a, b, c' form.","triggerScenarios":"Passing an integer, boolean, or arbitrary object to format_as_comma; a code path that feeds a revision count or a non-iterable config value into a messaging helper that calls format_as_comma; calling status()/format_as_comma with a single non-string scalar.","commonSituations":"A migration or command passes a numeric value where a list/tuple of names was expected; autogenerate diff rendering hitting an unexpected diff element type; user-facing message construction with a mis-typed argument.","solutions":["Pass a list, tuple, or other Iterable of strings instead of a scalar: format_as_comma(['t1','t2']).","If you have a single name, pass it as a string: format_as_comma('t1').","If None is appropriate (no items), pass None to get an empty string.","Add an isinstance check or convert scalars with str() before calling if a single value is intentional."],"exampleFix":"# before\nformat_as_comma(3)        # ValueError\nformat_as_comma(True)     # ValueError\n# after\nformat_as_comma(['t1','t2','t3'])\nformat_as_comma('single')\nformat_as_comma(None)","handlingStrategy":"type-guard","validationCode":"from collections.abc import Iterable\n\ndef safe_format_as_comma(value):\n    if value is None:\n        return ''\n    if isinstance(value, str):\n        return value\n    if isinstance(value, Iterable):\n        return ', '.join(value)\n    raise TypeError(f'format_as_comma expects None/str/Iterable, got {type(value).__name__}')","typeGuard":"from collections.abc import Iterable\nfrom typing import Union\ndef is_comma_formattable(v) -> bool:\n    return v is None or isinstance(v, (str, Iterable))","tryCatchPattern":"from alembic.util.messaging import format_as_comma\ntry:\n    s = format_as_comma(value)\nexcept ValueError:\n    s = str(value)  # fallback stringification","preventionTips":["Always pass list/tuple/str/None to format_as_comma.","Add type annotations on callers to catch scalar misuse at lint time.","Unit-test message helpers with representative types."],"tags":["alembic","messaging","type-mismatch","formatting","internal-api"],"analyzedSha":"44fb3450330204b222ff05135e1fbbbdb28c44db","analyzedAt":"2026-08-04T19:57:10.248Z","schemaVersion":2}