{"record":{"id":"d7a67c81443d557a","repo":"embassy-rs/embassy","slug":"the-read-size-for-the-concatenated-flashes-must-be","errorCode":null,"errorMessage":"The read size for the concatenated flashes must be the same","messagePattern":"The read size for the concatenated flashes must be the same","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-embedded-hal/src/flash/concat_flash.rs","lineNumber":20,"sourceCode":"use embedded_storage_async::nor_flash::{\n    MultiwriteNorFlash as AsyncMultiwriteNorFlash, NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash,\n};\n\n/// Convenience helper for concatenating two consecutive flashes into one.\n/// This is especially useful if used with \"flash regions\", where one may\n/// want to concatenate multiple regions into one larger region.\npub struct ConcatFlash<First, Second>(First, Second);\n\nimpl<First, Second> ConcatFlash<First, Second> {\n    /// Create a new flash that concatenates two consecutive flashes.\n    pub fn new(first: First, second: Second) -> Self {\n        Self(first, second)\n    }\n}\n\nconst fn get_read_size(first_read_size: usize, second_read_size: usize) -> usize {\n    if first_read_size != second_read_size {\n        panic!(\"The read size for the concatenated flashes must be the same\");\n    }\n    first_read_size\n}\n\nconst fn get_write_size(first_write_size: usize, second_write_size: usize) -> usize {\n    if first_write_size != second_write_size {\n        panic!(\"The write size for the concatenated flashes must be the same\");\n    }\n    first_write_size\n}\n\nconst fn get_max_erase_size(first_erase_size: usize, second_erase_size: usize) -> usize {\n    let max_erase_size = if first_erase_size > second_erase_size {\n        first_erase_size\n    } else {\n        second_erase_size\n    };\n    if max_erase_size % first_erase_size != 0 || max_erase_size % second_erase_size != 0 {","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-embedded-hal/src/flash/concat_flash.rs#L2-L38","documentation":"When concatenating two flashes with `ConcatFlash::new`, embassy-embedded-hal computes the combined READ_SIZE at compile time via the const fn `get_read_size`. If the two flashes declare different READ_SIZE constants, the panics fire because a single read granularity cannot represent both. This is a const-eval panic, so it usually fails during compilation of the const initializer.","triggerScenarios":"`ConcatFlash::new(flash_a, flash_b)` (or the type alias/const initializer feeding ReadNorFlash/AsyncReadNorFlash impls) where `First::READ_SIZE != Second::READ_SIZE`.","commonSituations":"Concatenating different flash chips (e.g. a 1-byte-read internal flash with a 4-byte-read SPI flash); upgrading a driver whose READ_SIZE constant changed; copy-pasting ConcatFlash config across boards with different second flash.","solutions":["Use flashes with identical READ_SIZE values, or wrap one flash in an adapter that normalizes its READ_SIZE","Check each flash's READ_SIZE associated constant in its NorFlash impl","Insert the two flashes in a different order/type so both share a read size","Implement a small wrapper flash type overriding READ_SIZE to the common value if reads are effectively byte-granular"],"exampleFix":"// before\nlet flash = ConcatFlash::new(spi_flash /* READ_SIZE=4 */, internal_flash /* READ_SIZE=1 */);\n// after\nlet flash = ConcatFlash::new(spi_flash, WrappedFlash::<_, 4>::new(internal_flash)); // aligned READ_SIZE=4","handlingStrategy":"validation","validationCode":"const fn read_sizes_match<A: NorFlash, B: NorFlash>() -> bool { A::READ_SIZE == B::READ_SIZE }\nconst _: () = assert!(read_sizes_match::<MyFlashA, MyFlashB>(), \"READ_SIZE mismatch for ConcatFlash\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check READ_SIZE of both flashes before combining with ConcatFlash","Wrap mismatched flashes in an adapter normalizing READ_SIZE","Add a const assert for flash constants in your board support crate","Re-verify flash constants after driver version bumps"],"tags":["embedded","flash","compile-time","panic","const-eval"],"backgroundTag":"invalid-config-value","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}