{"record":{"id":"8bcca35eef5d1211","repo":"pathwaycom/pathway","slug":"exactly-one-of-the-parameters-schema-or-unpacke","errorCode":null,"errorMessage":"exactly one of the parameters `schema` or `unpacked_columns` must be provided","messagePattern":"exactly one of the parameters `schema` or `unpacked_columns` must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/stdlib/utils/col.py","lineNumber":81,"sourceCode":"    >>> pw.debug.compute_and_print(unpack_table, include_id=False)\n    name   | age | pet\n    Alice  | 25  | dog\n    Bob    | 32  | cat\n    Carole | 28  | dog\n    >>> class SomeSchema(pw.Schema):\n    ...     name: str\n    ...     age: int\n    ...     pet: str\n    >>> unpack_table = pw.utils.col.unpack_col(t2.user, schema=SomeSchema)\n    >>> pw.debug.compute_and_print(unpack_table, include_id=False)\n    name   | age | pet\n    Alice  | 25  | dog\n    Bob    | 32  | cat\n    Carole | 28  | dog\n    \"\"\"\n\n    if (schema is None) == (len(unpacked_columns) == 0):\n        raise ValueError(\n            \"exactly one of the parameters `schema` or `unpacked_columns` must be provided\"\n        )\n\n    if schema is not None:\n        unpacked_columns = tuple(schema.column_names())\n    colrefs = [pw.this[unpacked_column] for unpacked_column in unpacked_columns]\n    kw = {colref.name: column[i] for i, colref in enumerate(colrefs)}\n    result = column.table.select(**kw)\n    if schema is not None:\n        result = result.update_types(**schema.typehints())\n    return result\n\n\n@check_arg_types\n@trace_user_frame\ndef unpack_col_dict(\n    column: pw.ColumnReference,\n    schema: type[pw.Schema],","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/stdlib/utils/col.py#L63-L99","documentation":"pw.utils.col.unpack_col expands a composite column (e.g. a Schema-typed or Json column) into separate table columns. It accepts the target field names either via a schema= class or via positional unpacked_columns strings, and requires exactly one of the two: the check `(schema is None) == (len(unpacked_columns) == 0)` raises ValueError when both are provided or neither is.","triggerScenarios":"pw.utils.col.unpack_col(t.user, schema=SomeSchema, 'name', 'age') (both given); pw.utils.col.unpack_col(t.user) with no schema and no column names (neither given).","commonSituations":"Copy-pasting a call that evolved from positional names to a schema without removing the old arguments; refactoring tutorials where the schema argument is deleted but no replacement names are added; passing unpacked_columns as a list that is accidentally empty.","solutions":["Provide exactly one: unpack_col(t.user, schema=SomeSchema) OR unpack_col(t.user, 'name', 'age')","If using schema=, also get type casting via update_types for free","Guard in wrapper code: assert (schema is None) != (not unpacked_columns) before calling"],"exampleFix":"# before\nunpacked = pw.utils.col.unpack_col(t.user, schema=UserSchema, 'name', 'age')\n\n# after\nunpacked = pw.utils.col.unpack_col(t.user, schema=UserSchema)","handlingStrategy":"validation","validationCode":"assert (schema is not None) != (len(unpacked_columns) == 0), 'pass exactly one of schema= or unpacked_columns'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose one style per codebase (schema= for typed unpacking, names for quick access) and stick to it","When migrating calls to schema=, delete the old positional column names in the same commit"],"tags":["pathway","unpack","argument-validation"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}