{"record":{"id":"6907b124b2c7d7c3","repo":"pola-rs/polars","slug":"worksheet-object-requires-the-parent-workbook-obje","errorCode":null,"errorMessage":"worksheet object requires the parent workbook object; found workbook={workbook!r}","messagePattern":"worksheet object requires the parent workbook object; found workbook=(.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/spreadsheet/_write_utils.py","lineNumber":611,"sourceCode":"    from xlsxwriter.worksheet import Worksheet\n\n    if isinstance(workbook, Workbook):\n        wb, can_close = workbook, False\n        ws = (\n            worksheet\n            if (\n                isinstance(worksheet, Worksheet)\n                and _xl_worksheet_in_workbook(wb, worksheet)\n            )\n            # Argument `Worksheet | str | None` is not assignable to parameter `name`\n            # with type `str`.\n            else wb.get_worksheet_by_name(\n                name=worksheet  # pyrefly: ignore[bad-argument-type]\n            )\n        )\n    elif isinstance(worksheet, Worksheet):\n        msg = f\"worksheet object requires the parent workbook object; found workbook={workbook!r}\"\n        raise TypeError(msg)\n    else:\n        workbook_options = {\n            \"use_zip64\": use_zip64,\n            \"nan_inf_to_errors\": True,\n            \"strings_to_formulas\": False,\n            \"default_date_format\": _XL_DEFAULT_DTYPE_FORMATS_[Date],\n        }\n        if isinstance(workbook, BytesIO):\n            wb, ws, can_close = Workbook(workbook, workbook_options), None, True\n        else:\n            file: Path | IO[bytes]\n            if workbook is None:\n                file = Path(\"dataframe.xlsx\")\n            elif isinstance(workbook, str):\n                file = Path(workbook)\n            else:\n                file = workbook\n","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/spreadsheet/_write_utils.py#L593-L629","documentation":"TypeError raised by _xl_setup_workbook during write_excel when worksheet is an xlsxwriter Worksheet object but the workbook parameter is not the corresponding xlsxwriter Workbook. A live worksheet handle is only meaningful relative to its owning workbook; if workbook is None, a path, a BytesIO, or anything else, polars would have to create a new workbook that cannot contain that worksheet, so it refuses.","triggerScenarios":"pl.write_excel(df, worksheet=ws) with no workbook argument; or pl.write_excel(df, workbook=BytesIO(), worksheet=ws); or workbook='out.xlsx' (a path) together with a worksheet object.","commonSituations":"Reusing a worksheet obtained from wb.get_worksheet_by_name()/add_worksheet() but forgetting to pass wb back in; switching the workbook target from an object to a file path/BytesIO while keeping the worksheet handle; helper functions that accept an optional worksheet without threading the workbook through.","solutions":["Always pass the parent: pl.write_excel(df, workbook=wb, worksheet=ws).","Or drop the worksheet object and use its name: pl.write_excel(df, workbook='out.xlsx', worksheet='Sheet1').","In helper functions, require workbook and worksheet to be passed as a pair (or derive the sheet by name only)."],"exampleFix":"# before\nws = wb.add_worksheet('data')\npl.write_excel(df, worksheet=ws)  # workbook missing\n\n# after\npl.write_excel(df, workbook=wb, worksheet=ws)","handlingStrategy":"type-guard","validationCode":"from xlsxwriter import Workbook\nfrom xlsxwriter.worksheet import Worksheet\n\nif isinstance(worksheet, Worksheet) and not isinstance(workbook, Workbook):\n    raise TypeError('worksheet object requires its parent Workbook in `workbook=`')\npl.write_excel(df, workbook=workbook, worksheet=worksheet)","typeGuard":"import xlsxwriter\n\ndef has_parent_workbook(workbook: object, worksheet: object) -> bool:\n    return not isinstance(worksheet, xlsxwriter.worksheet.Worksheet) or isinstance(workbook, xlsxwriter.Workbook)","tryCatchPattern":"try:\n    pl.write_excel(df, worksheet=ws)\nexcept TypeError as e:\n    if 'requires the parent workbook object' in str(e):\n        pl.write_excel(df, workbook=ws._parent if hasattr(ws, '_parent') else None, worksheet=ws)\n    else:\n        raise","preventionTips":["A Worksheet handle is only usable together with workbook=<its Workbook>.","If you only have a sheet name, pass the string — polars resolves it inside the workbook/path target.","Never mix worksheet objects with workbook as a path, None, or BytesIO."],"tags":["excel","spreadsheet","write-excel","workbook","worksheet","type-error"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}