{"record":{"id":"16761428e6adef2d","repo":"pola-rs/polars","slug":"invalid-value-for-polars-ideal-sink-morsel-size-rows-x","errorCode":null,"errorMessage":"invalid value for POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS: {x}","messagePattern":"invalid value for POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-stream/src/nodes/io_sinks/writers/interface.rs","lineNumber":71,"sourceCode":"    fn poll(\n        mut self: std::pin::Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> std::task::Poll<Self::Output> {\n        use std::task::Poll;\n\n        let file: Result<_, tokio::task::JoinError> = futures::ready!(self.handle.poll_unpin(cx));\n        let file: PolarsResult<WriteTarget> = file.unwrap();\n\n        Poll::Ready(file.map(|file| (file, self.sync_on_close)))\n    }\n}\n\n/// Load ideal morsel size configuration from environment variables.\npub(super) fn ideal_sink_morsel_size_env() -> (Option<NonZeroIdxSize>, Option<NonZeroU64>) {\n    let num_rows = std::env::var(\"POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS\")\n        .map(|x| {\n            x.parse::<NonZeroIdxSize>().ok().unwrap_or_else(|| {\n                panic!(\"invalid value for POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS: {x}\")\n            })\n        })\n        .ok();\n\n    let num_bytes = std::env::var(\"POLARS_IDEAL_SINK_MORSEL_SIZE_BYTES\")\n        .map(|x| {\n            x.parse::<NonZeroU64>().ok().unwrap_or_else(|| {\n                panic!(\"invalid value for POLARS_IDEAL_SINK_MORSEL_SIZE_BYTES: {x}\")\n            })\n        })\n        .ok();\n\n    (\n        num_rows,\n        num_bytes.or(num_rows.is_some().then_some(NonZeroU64::MAX)),\n    )\n}\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-stream/src/nodes/io_sinks/writers/interface.rs#L53-L89","documentation":"POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS optionally overrides the ideal row count per morsel fed to sink writers. Polars parses it as NonZeroIdxSize; a value that is zero, negative, or not a valid size literal causes a panic during streaming sink setup.","triggerScenarios":"Setting POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS to something like '0', 'abc', or a non-size token, then executing a sink (sink_parquet/sink_csv/...); read in ideal_sink_morsel_size_env, used by initialized_state and target_sink_morsel_size.","commonSituations":"Performance tuning sink morsel sizes from a runbook with a typo; scripting that exports empty strings when the tuning value is missing.","solutions":["Set a positive integer row count, e.g. export POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS=10000.","Unset the variable to use the default morsel sizing.","Check surrounding scripts for empty-string exports and strip whitespace/units."],"exampleFix":"# before\nexport POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS=0\n# after\nexport POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS=10000","handlingStrategy":"validation","validationCode":"import os\nv = os.environ.get(\"POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS\")\nif v is not None:\n    assert v.isdigit() and int(v) > 0, f\"must be positive integer rows, got {v!r}\"","typeGuard":"def is_positive_int(s: str) -> bool:\n    return s.isdigit() and int(s) > 0","tryCatchPattern":"v = os.environ.get(\"POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS\", \"\")\nif v and not v.isdigit():\n    os.environ.pop(\"POLARS_IDEAL_SINK_MORSEL_SIZE_ROWS\", None)  # use library default","preventionTips":["Only export these vars when the tuning value is actually present","Strip whitespace and units before exporting","Centralize POLARS_* tuning in one validated config module","Never default to empty string; default to unset"],"tags":["environment-variable","panic","configuration","morsel"],"backgroundTag":"invalid-env-var-value","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}