{"record":{"id":"3b1744b9af246410","repo":"dbt-labs/dbt-core","slug":"reduce-key-originates-from-relations-by-schema","errorCode":null,"errorMessage":"reduce key originates from relations_by_schema","messagePattern":"reduce key originates from relations_by_schema","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/metadata/redshift/mod.rs","lineNumber":860,"sourceCode":"                quote_ident(AdapterType::Redshift, database),\n                quote_ident(AdapterType::Redshift, schema),\n            );\n            let ctx = QueryCtx::default().with_desc(\"Extracting freshness via SHOW TABLES\");\n            let (_, agate_table) =\n                adapter.query(&ctx, &mut *conn, &sql, None, token_clone.clone())?;\n            Ok(agate_table.original_record_batch())\n        };\n\n        type Acc = BTreeMap<String, MetadataFreshness>;\n        let reduce_f = move |acc: &mut Acc,\n                             key: (String, String),\n                             batch_res: AdapterResult<Arc<RecordBatch>>|\n              -> Result<(), Cancellable<AdapterError>> {\n            let batch = batch_res?;\n            // `key` came from `relations_by_schema.keys()`, so it is always present.\n            let relations = relations_by_schema\n                .get(&key)\n                .expect(\"reduce key originates from relations_by_schema\");\n            acc.extend(parse_show_tables_freshness_batch(&batch, relations)?);\n            Ok(())\n        };\n\n        let map_reduce = MapReduce::new(factory, Box::new(map_f), Box::new(reduce_f), None);\n        map_reduce.run(Arc::new(keys), token)\n    }\n}\n\n/// Parse a `SHOW TABLES FROM SCHEMA` result batch into a freshness map keyed by\n/// each matching relation's semantic FQN. Rows whose table is not in the\n/// requested set are ignored.\nfn parse_show_tables_freshness_batch(\n    batch: &RecordBatch,\n    relations: &[Arc<dyn BaseRelation>],\n) -> AdapterResult<BTreeMap<String, MetadataFreshness>> {\n    let mut out = BTreeMap::new();\n    if batch.num_rows() == 0 {","sourceCodeStart":842,"sourceCodeEnd":878,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/metadata/redshift/mod.rs#L842-L878","documentation":"In `run_via_show_tables` (crates/dbt-adapter/src/metadata/redshift/mod.rs:860), the reduce closure re-fetches `relations_by_schema.get(&key)` and asserts the key is always present because keys were produced from `relations_by_schema.keys()`. The panic fires only if the map was mutated/cleared between building the keys and running the map-reduce, or the key set was derived inconsistently.","triggerScenarios":"Running the Redshift SHOW TABLES freshness map-reduce after `relations_by_schema` has been modified or a key was produced from a different map instance (e.g. cloned relations map while iterating keys of another).","commonSituations":"Concurrent mutation of the relations map during the run; refactors that build `keys` from a filtered/different collection; partial map-reduce retries with stale keys.","solutions":["Ensure `keys` is derived from the exact same `relations_by_schema` instance passed to the reduce closure and is not mutated during the run","Replace `.expect` with graceful handling: skip unknown keys and return Ok","Clone the relations entry into the key tuple so no lookup is needed in reduce","Add a debug assertion/log capturing the missing key to catch the producer bug"],"exampleFix":"// before\n.expect(\"reduce key originates from relations_by_schema\");\n// after\nlet Some(relations) = relations_by_schema.get(&key) else { return Ok(()) };","handlingStrategy":"validation","validationCode":"// ensure keys and map come from the same source\nassert!(keys.iter().all(|k| relations_by_schema.contains_key(k)));","typeGuard":"fn keys_match_map(keys: &[Key], map: &HashMap<Key, Relations>) -> bool {\n    keys.iter().all(|k| map.contains_key(k))\n}","tryCatchPattern":"std::panic::catch_unwind(AssertUnwindSafe(|| map_reduce.run(Arc::new(keys), token)))","preventionTips":["Never mutate relations_by_schema between key collection and reduce","Derive keys from the same map instance passed to reduce","Avoid sharing the map across concurrent runs","Skip-and-log unknown keys instead of asserting"],"tags":["rust","panic","map-reduce","redshift"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}