{"record":{"id":"3ffd6010d97e3c3c","repo":"pola-rs/polars","slug":"not-implemented-3ffd60","errorCode":null,"errorMessage":"not implemented","messagePattern":"not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-ops/src/frame/join/asof/groups.rs","lineNumber":356,"sourceCode":"    left_by: &mut DataFrame,\n    right_by: &mut DataFrame,\n    strategy: AsofStrategy,\n    allow_eq: bool,\n) -> PolarsResult<IdxArr>\nwhere\n    for<'a> T::Physical<'a>: TotalOrd,\n{\n    let right_asof = left_asof.unpack_series_matching_type(right_asof)?;\n\n    let filter = |_a: T::Physical<'_>, _b: T::Physical<'_>| true;\n    match strategy {\n        AsofStrategy::Backward => dispatch_join_by_type::<T, AsofJoinBackwardState, _>(\n            left_asof, right_asof, left_by, right_by, filter, allow_eq,\n        ),\n        AsofStrategy::Forward => dispatch_join_by_type::<T, AsofJoinForwardState, _>(\n            left_asof, right_asof, left_by, right_by, filter, allow_eq,\n        ),\n        AsofStrategy::Nearest => unimplemented!(),\n    }\n}\n\n#[allow(clippy::too_many_arguments)]\nfn dispatch_join_strategy_numeric<T: PolarsNumericType>(\n    left_asof: &ChunkedArray<T>,\n    right_asof: &Series,\n    left_by: &mut DataFrame,\n    right_by: &mut DataFrame,\n    strategy: AsofStrategy,\n    tolerance: Option<AnyValue<'static>>,\n    allow_eq: bool,\n) -> PolarsResult<IdxArr> {\n    let right_ca = left_asof.unpack_series_matching_type(right_asof)?;\n\n    if let Some(tol) = tolerance {\n        let native_tolerance: T::Native = tol.try_extract()?;\n        let abs_tolerance = native_tolerance.abs_diff(T::Native::zero());","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/crates/polars-ops/src/frame/join/asof/groups.rs#L338-L374","documentation":"The grouped asof-join implementation (join_asof with by= groups) only implements the Backward and Forward strategies; AsofStrategy::Nearest reaches unimplemented!(). Ungrouped asof joins do support nearest, but the per-group state machines for it were never written.","triggerScenarios":"df.join_asof(other, on=\"ts\", by=[\"id\"], strategy=\"nearest\") - an asof join with both the by parameter and strategy='nearest'.","commonSituations":"Time-series lookups per entity (sensor per device, quotes per symbol) where the user wants the closest timestamp in each group; code that worked without by= and later added grouping columns.","solutions":["Drop the by= argument (sort both frames on the asof key, plus groups if acceptable) so the non-grouped nearest implementation is used","Use strategy='backward' or 'forward' with a tolerance, which are implemented for grouped asof","Emulate nearest per group: for each group slice, run join_asof twice (backward and forward) and pick the closer match, or use search_sorted on the sorted right keys"],"exampleFix":"# before\nout = left.join_asof(right, on=\"ts\", by=\"id\", strategy=\"nearest\")  # panics\n\n# after (implemented path)\nout = left.sort(\"ts\").join_asof(\n    right.sort(\"ts\"), on=\"ts\", by=\"id\", strategy=\"backward\"\n)","handlingStrategy":"validation","validationCode":"def grouped_asof_supported(strategy: str, by: list[str] | None) -> bool:\n    return not (by and strategy == \"nearest\")","typeGuard":"def grouped_asof_supported(strategy: str, by: list[str] | None) -> bool:\n    return not (by and strategy == \"nearest\")","tryCatchPattern":null,"preventionTips":["Remember: grouped asof supports backward/forward only; nearest requires dropping by=","Sort both frames on the asof key before join_asof regardless of strategy"],"tags":["rust","polars","panic","unimplemented","asof-join","join","nearest","grouped"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}