{"record":{"id":"516d593e618c8ab5","repo":"apache/cassandra","slug":"invalid-composite-string-it-should-start-and-end","errorCode":null,"errorMessage":"Invalid composite string, it should start and end with matching parentheses: {}","messagePattern":"Invalid composite string, it should start and end with matching parentheses: (.+?)","errorType":"validation","errorClass":"ParseError","httpStatus":null,"severity":"error","filePath":"pylib/cqlshlib/copyutil.py","lineNumber":1989,"sourceCode":"            types, \"val\" should be at least 2 characters long, the first char should be an\n            open parenthesis and the last char should be a matching closing parenthesis. We could also\n            check exactly which parenthesis type depending on the caller, but I don't want to enforce\n            too many checks that don't necessarily provide any additional benefits, and risk breaking\n            data that could previously be imported, even if strictly speaking it is incorrect CQL.\n            For example, right now we accept sets that start with '[' and ']', I don't want to break this\n            by enforcing '{' and '}' in a minor release.\n            \"\"\"\n            def is_open_paren(cc):\n                return cc == '{' or cc == '[' or cc == '('\n\n            def is_close_paren(cc):\n                return cc == '}' or cc == ']' or cc == ')'\n\n            def paren_match(c1, c2):\n                return (c1 == '{' and c2 == '}') or (c1 == '[' and c2 == ']') or (c1 == '(' and c2 == ')')\n\n            if len(val) < 2 or not paren_match(val[0], val[-1]):\n                raise ParseError('Invalid composite string, it should start and end with matching parentheses: {}'\n                                 .format(val))\n\n            ret = []\n            last = 1\n            level = 0\n            quote = False\n            for i, c in enumerate(val):\n                if c == '\\'':\n                    quote = not quote\n                elif not quote:\n                    if is_open_paren(c):\n                        level += 1\n                    elif is_close_paren(c):\n                        level -= 1\n                    elif c == sep and level == 1:\n                        ret.append(val[last:i])\n                        last = i + 1\n            else:","sourceCodeStart":1971,"sourceCodeEnd":2007,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/pylib/cqlshlib/copyutil.py#L1971-L2007","documentation":"When parsing a composite value (map, set, list, tuple, or user type) from CSV during COPY FROM, the string must start and end with a matched pair of parentheses/brackets/braces. Anything shorter than 2 chars or with mismatched outer brackets is rejected with this ParseError.","triggerScenarios":"COPY FROM a CSV cell for a collection/UDT column whose value lacks the wrapping braces, e.g. 'a,b' instead of '{a,b}' for a set, or '(1,2]' mixing bracket types, or an empty cell parsed as a collection.","commonSituations":"Hand-edited CSVs missing the outer braces, exports from other tools that serialize collections differently, truncated fields, quoting issues that strip the brackets during CSV parsing.","solutions":["Wrap collection values in matching delimiters: list/tuple use [..]/(..), set/map use {..}, UDT uses (..)","Check CSV quoting so delimiters are not consumed by the CSV parser","Inspect the offending row in the CSV and correct the value format"],"exampleFix":"// before\n1, a,b\n// after (for a set column)\n1,\"{a,b}\"","handlingStrategy":"validation","validationCode":"import re\nfor col, v in row.items():\n    if col in collection_cols:\n        pairs = {'{':'}','[':']','(':')'}\n        if not (v and v[0] in pairs and v[-1] == pairs[v[0]]):\n            raise ValueError(f\"{col}: value {v!r} lacks matching delimiters\")","typeGuard":null,"tryCatchPattern":"try:\n    run_copy_from(...)\nexcept ParseError as e:\n    print(f\"Malformed collection value: {e}\")  # fix that CSV cell","preventionTips":["Always quote collection cells in CSV","Export collections from Cassandra itself to get canonical formatting","Don't hand-edit collection strings without re-checking delimiters"],"tags":["cqlsh","copy","parsing","collections"],"backgroundTag":"invalid-argument-format","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}