{"record":{"id":"b03a6f7db1e44021","repo":"astrid-runtime/astrid","slug":"fastcdc-candidate-has-non-fastcdc-parameters","errorCode":null,"errorMessage":"FastCDC candidate has non-FastCDC parameters","messagePattern":"FastCDC candidate has non-FastCDC parameters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-chunker-evidence/src/algorithm.rs","lineNumber":141,"sourceCode":"                    visit(chunk)\n                })?;\n            },\n            Algorithm::MothCaterpillar => {\n                let mut chunker = MothReadChunker::try_new(reader, minimum, maximum)?;\n                while let Some(segment) = chunker.next()? {\n                    for _ in 0..segment.chunk_count() {\n                        visit(segment.dedup_key())?;\n                    }\n                }\n            },\n        }\n        Ok(())\n    }\n\n    fn fastcdc_target_bytes(&self) -> Result<u32> {\n        match self.parameters {\n            Parameters::FastCdc2020 { target_bytes, .. } => Ok(target_bytes),\n            _ => bail!(\"FastCDC candidate has non-FastCDC parameters\"),\n        }\n    }\n}\n\npub fn candidates(target_kib: u32) -> Result<Vec<Candidate>> {\n    if !(8..=256).contains(&target_kib) || !target_kib.is_power_of_two() {\n        bail!(\"target KiB must be a power of two in 8..=256\");\n    }\n    let target = target_kib\n        .checked_mul(1024)\n        .ok_or_else(|| anyhow::anyhow!(\"target byte size overflow\"))?;\n\n    let fast_minimum = target / 4;\n    let fast_maximum = target\n        .checked_mul(4)\n        .ok_or_else(|| anyhow::anyhow!(\"FastCDC maximum overflow\"))?;\n    let narrow_minimum = checked_ratio(target, 3, 4, \"narrow MinCDC minimum\")?;\n    let narrow_maximum = checked_ratio(target, 5, 4, \"narrow MinCDC maximum\")?;","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-chunker-evidence/src/algorithm.rs#L123-L159","documentation":"In the chunker-evidence crate, `fastcdc_target_bytes()` extracts the target size from a candidate's parameters and only accepts `Parameters::FastCdc2020`. Any other parameter variant reaching this code path is an internal invariant violation: a FastCDC candidate was constructed with non-FastCDC parameters.","triggerScenarios":"Calling `fastcdc_target_bytes()` (via `visit_records`/`visit_boundary_chunks`) on a candidate whose `parameters` enum is not `Parameters::FastCdc2020`.","commonSituations":"A bug in candidate construction mixing parameter kinds; future parameter variants added without updating this matcher; code that assumes all candidates are FastCDC when the candidates list can contain other algorithms.","solutions":["Check how the candidate was built and ensure `Parameters::FastCdc2020` is used for FastCDC candidates.","Filter candidates by algorithm before calling FastCDC-specific visitors.","If a new Parameters variant was added, extend this matcher to handle it explicitly."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Only pass FastCDC candidates to FastCDC-specific visitors\ncandidates.iter().filter(|c| matches!(c.parameters, Parameters::FastCdc2020 { .. }))","typeGuard":"fn is_fastcdc(p: &Parameters) -> bool {\n    matches!(p, Parameters::FastCdc2020 { .. })\n}","tryCatchPattern":"match fastcdc_target_bytes(&candidate) {\n    Ok(target) => use_target(target),\n    Err(e) => log::error!(\"non-FastCDC params reached FastCDC path: {e}\"), // fix construction site\n}","preventionTips":["Construct FastCDC candidates only from Parameters::FastCdc2020","Filter candidate lists by algorithm before algorithm-specific processing","Update fastcdc_target_bytes when adding new Parameters variants"],"tags":["invariant","chunker","fastcdc","parameters"],"backgroundTag":"internal-invariant-violation","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}