{"record":{"id":"c0afc32398c6181a","repo":"databendlabs/databend","slug":"transform-aggregator-hash-table-already-moved-ou","errorCode":null,"errorMessage":"[TRANSFORM-AGGREGATOR] Hash table already moved out","messagePattern":"\\[TRANSFORM-AGGREGATOR\\] Hash table already moved out","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/service/src/pipelines/processors/transforms/aggregator/transform_aggregate_partial.rs","lineNumber":187,"sourceCode":"    ) -> Vec<ProjectedBlock<'a>> {\n        aggregate_functions_arguments\n            .iter()\n            .map(|function_arguments| ProjectedBlock::project(function_arguments, block))\n            .collect::<Vec<_>>()\n    }\n\n    #[inline(always)]\n    fn execute_one_block(&mut self, block: DataBlock) -> Result<()> {\n        let group_columns = ProjectedBlock::project(&self.params.group_columns, &block);\n        let rows_num = block.num_rows();\n        let block_bytes = block.memory_size();\n\n        self.statistics.record_block(rows_num, block_bytes);\n\n        {\n            match &mut self.hash_table {\n                HashTable::MovedOut => {\n                    unreachable!(\"[TRANSFORM-AGGREGATOR] Hash table already moved out\")\n                }\n                HashTable::AggregateHashTable(hashtable) => {\n                    let params_columns = Self::aggregate_arguments(\n                        &block,\n                        &self.params.aggregate_functions_arguments,\n                    );\n                    let agg_states = (&[]).into();\n\n                    let _ = hashtable.add_groups(\n                        &mut self.probe_state,\n                        group_columns,\n                        &params_columns,\n                        agg_states,\n                        rows_num,\n                    )?;\n                    Ok(())\n                }\n            }","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/service/src/pipelines/processors/transforms/aggregator/transform_aggregate_partial.rs#L169-L205","documentation":"TransformPartialAggregate::execute_one_block requires ownership of the partial aggregation hash table to absorb a block. If self.hash_table is HashTable::MovedOut — the table was already moved out (e.g. by on_finish taking it) — the code hits unreachable!, guarding the invariant that no data is processed after the table was handed off.","triggerScenarios":"transform() delivers another input block after the hash table was moved out via std::mem::take (e.g. on_finish ran before remaining input drained), which can happen with pipeline event-ordering bugs or retry/replay of input blocks.","commonSituations":"Executor bugs where finish precedes the last transform calls; duplicated blocks in the pipeline driver; regressions from refactoring the HashTable enum.","solutions":["Upgrade/retry; verify only one finish call and that all input blocks arrive before on_finish","If a custom pipeline feeds this transform, ensure blocks stop before finish","File a bug with query profile and stack trace if reproducible"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn table_alive(ht: &HashTable) -> bool {\n    matches!(ht, HashTable::AggregateHashTable(_))\n}","tryCatchPattern":"match res {\n    Err(e) if e.message().contains(\"Hash table already moved out\") => {\n        // query abort; retry on fixed version; report with plan + stack trace\n    }\n    ...\n}","preventionTips":["Never invoke on_finish while input blocks remain queued for the transform","Add lifecycle assertions in pipeline drivers (no transform after finish)","Keep std::mem::take of hash tables confined to on_finish","Run executor state-machine tests after HashTable enum changes"],"tags":["internal","aggregation","state-machine","unreachable"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}