{"record":{"id":"d7b32445e06cdb80","repo":"embassy-rs/embassy","slug":"invalid-filterconfig-emptyfilterconfig-a-filter","errorCode":null,"errorMessage":"Invalid FilterConfig (EmptyFilterConfig)! A FilterConfig cannot be empty.","messagePattern":"Invalid FilterConfig \\(EmptyFilterConfig\\)! A FilterConfig cannot be empty\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-mcxa/src/flexcan/filter.rs","lineNumber":121,"sourceCode":"impl<'a> FilterConfig<'a> {\n    /// This is an internal function that should only be\n    /// called via the `filters` macro.\n    ///\n    /// This function calls Self::try_new(), but panics when an error is returned. This generates\n    /// a nice compile-time error, so long as `__filters()` is called from a `const` context. The purpose\n    /// of the `filters` macro is to ensure `__filters()` can only be called from a `const` context,\n    /// so we can do all the nice compile-time validation stuff without the possibility of a runtime panic.\n    #[doc(hidden)]\n    pub const fn __filters(filters: &'a [Filter]) -> Self {\n        match Self::try_new(filters) {\n            Ok(me) => me,\n            Err(FilterConfigError::TooManyFilters) => {\n                panic!(\n                    \"Invalid FilterConfig (TooManyFilters)! A FilterConfig must adhere to the constraint `2*(num_extended) + (num_standard) <= 32`.\"\n                );\n            }\n            Err(FilterConfigError::EmptyFilterConfig) => {\n                panic!(\"Invalid FilterConfig (EmptyFilterConfig)! A FilterConfig cannot be empty.\");\n            }\n        }\n    }\n\n    /// Creates a new `FilterConfig` from a declarative list of filters.\n    ///\n    /// The preferred way of constructing a `FilterConfig` is through the\n    /// `filters!()` macro (since it evaluates at compile-time), but this function\n    /// may be useful if you need to reconfigure filters based on runtime values.\n    pub const fn try_new(filters: &'a [Filter]) -> Result<Self, FilterConfigError> {\n        if filters.is_empty() {\n            return Err(FilterConfigError::EmptyFilterConfig);\n        }\n\n        // Calculate how many of each type of filter there is\n        let mut num_standard = 0;\n        let mut num_extended = 0;\n        let mut i = 0;","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-mcxa/src/flexcan/filter.rs#L103-L139","documentation":"This panic fires when a FlexCAN `FilterConfig` is constructed from an empty filter list. The hardware message-buffer filter table must contain at least one filter; an empty table has no defined meaning, so `try_new` returns `EmptyFilterConfig` and the const constructor `__filters` turns that into a panic.","triggerScenarios":"Calling `FilterConfig::__filters(&[])` or passing a zero-length slice/array, often from a dynamically-built filter list that ended up empty.","commonSituations":"Building filters from a config file or user setting that specified none; a const-evaluated empty array after conditional filtering removed all entries; forgetting to add the first filter.","solutions":["Pass at least one `Filter` to `__filters` (e.g. accept-all or the specific IDs you need).","If 'receive everything' is intended, add a single catch-all filter rather than an empty list.","Use `FilterConfig::try_new` first in non-const code to handle the error instead of panicking."],"exampleFix":"// before\nlet cfg = FilterConfig::__filters(&[]);\n// after\nlet cfg = FilterConfig::__filters(&[Filter::standard(0x123)]);","handlingStrategy":"validation","validationCode":"if filters.is_empty() {\n    // provide a default catch-all or bail before calling __filters\n    panic!(\"at least one CAN filter required\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include at least one filter (a catch-all if everything should pass).","Validate dynamically-built filter lists for emptiness before constructing FilterConfig.","Use FilterConfig::try_new to get an error instead of a panic."],"tags":["embedded","rust","can","filter","empty-input"],"backgroundTag":"empty-required-field","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"}