{"record":{"id":"d8970e0d2d670edf","repo":"pola-rs/polars","slug":"cannot-create-string-column-without-an-offsets-buf","errorCode":null,"errorMessage":"cannot create String column without an offsets buffer","messagePattern":"cannot create String column without an offsets buffer","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/interchange/from_dataframe.py","lineNumber":119,"sourceCode":"        buffers[\"validity\"], column, dtype, data_buffer, offset, allow_copy=allow_copy\n    )\n    return pl.Series._from_buffers(dtype, data=data_buffer, validity=validity_buffer)\n\n\ndef _string_column_to_series(column: Column, *, allow_copy: bool) -> Series:\n    if column.size() == 0:\n        return pl.Series(dtype=String)\n    elif not allow_copy:\n        msg = \"string buffers must be converted\"\n        raise CopyNotAllowedError(msg)\n\n    buffers = column.get_buffers()\n    offset = column.offset\n\n    offsets_buffer_info = buffers[\"offsets\"]\n    if offsets_buffer_info is None:\n        msg = \"cannot create String column without an offsets buffer\"\n        raise RuntimeError(msg)\n    offsets_buffer = _construct_offsets_buffer(\n        *offsets_buffer_info, offset, allow_copy=allow_copy\n    )\n\n    buffer, dtype = buffers[\"data\"]\n    data_buffer = _construct_data_buffer(\n        buffer, dtype, buffer.bufsize, offset=0, allow_copy=allow_copy\n    )\n\n    # First construct a Series without a validity buffer\n    # to allow constructing the validity buffer from a sentinel value\n    data_buffers = [data_buffer, offsets_buffer]\n    data = pl.Series._from_buffers(String, data=data_buffers, validity=None)\n\n    # Add the validity buffer if present\n    validity_buffer = _construct_validity_buffer(\n        buffers[\"validity\"], column, String, data, offset, allow_copy=allow_copy\n    )","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/interchange/from_dataframe.py#L101-L137","documentation":"Raised when a String column coming from an interchange producer reports no offsets buffer (buffers['offsets'] is None). The protocol requires string columns to provide both a data buffer and an offsets buffer; without offsets, element boundaries are unknown and a String Series cannot be constructed. This always indicates a malformed or non-conforming producer implementation.","triggerScenarios":"A custom or third-party __dataframe__ implementation whose Column.get_buffers() returns None for the 'offsets' key of a non-empty String column.","commonSituations":"Writing your own interchange producer and forgetting the offsets buffer; using an early or minimal producer backend; protocol spec drift between producer and polars versions.","solutions":["Fix the producer: return a (buffer, dtype) tuple for buffers['offsets'] for every String column","Validate the producer against the reference interchange consumer tests before integration","If the producer cannot be fixed, bypass the protocol and move the data through Arrow (pl.from_arrow)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def producer_string_columns_have_offsets(df) -> bool:\n    proto = df.__dataframe__(allow_copy=False)\n    for col in proto.get_columns():\n        if col.dtype[0] == 21 and col.size() > 0:  # 21 == DtypeKind.STRING\n            if col.get_buffers()['offsets'] is None:\n                return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    out = pl.from_dataframe(df)\nexcept RuntimeError as e:\n    if 'without an offsets buffer' in str(e):\n        # producer is non-conforming; bypass interchange\n        out = pl.from_arrow(df.to_arrow())\n    else:\n        raise","preventionTips":["When writing a producer, always return an offsets buffer for String columns","Validate new producers against the reference interchange conformance tests before integration","Keep an Arrow fallback path for producer bugs - it sidesteps the protocol entirely"],"tags":["polars","interchange-protocol","string","producer-bug","runtime-error"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}