diff --git a/bazarr/app/config.py b/bazarr/app/config.py
index b0a8c62ba..5e5b5ac04 100644
--- a/bazarr/app/config.py
+++ b/bazarr/app/config.py
@@ -37,6 +37,12 @@ def validate_ip_address(ip_string):
except ValueError:
return False
+def validate_tags(tags):
+ if not tags:
+ return True
+
+ return all(re.match( r'^[a-z0-9_-]+$', item) for item in tags)
+
ONE_HUNDRED_YEARS_IN_MINUTES = 52560000
ONE_HUNDRED_YEARS_IN_HOURS = 876000
@@ -178,7 +184,7 @@ validators = [
Validator('sonarr.only_monitored', must_exist=True, default=False, is_type_of=bool),
Validator('sonarr.series_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440, 10080, ONE_HUNDRED_YEARS_IN_MINUTES]),
- Validator('sonarr.excluded_tags', must_exist=True, default=[], is_type_of=list),
+ Validator('sonarr.excluded_tags', must_exist=True, default=[], is_type_of=list, condition=validate_tags),
Validator('sonarr.excluded_series_types', must_exist=True, default=[], is_type_of=list),
Validator('sonarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
Validator('sonarr.exclude_season_zero', must_exist=True, default=False, is_type_of=bool),
@@ -201,7 +207,7 @@ validators = [
Validator('radarr.only_monitored', must_exist=True, default=False, is_type_of=bool),
Validator('radarr.movies_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440, 10080, ONE_HUNDRED_YEARS_IN_MINUTES]),
- Validator('radarr.excluded_tags', must_exist=True, default=[], is_type_of=list),
+ Validator('radarr.excluded_tags', must_exist=True, default=[], is_type_of=list, condition=validate_tags),
Validator('radarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
Validator('radarr.defer_search_signalr', must_exist=True, default=False, is_type_of=bool),
Validator('radarr.sync_only_monitored_movies', must_exist=True, default=False, is_type_of=bool),
diff --git a/frontend/src/pages/Settings/Radarr/index.tsx b/frontend/src/pages/Settings/Radarr/index.tsx
index b2e858178..264c78924 100644
--- a/frontend/src/pages/Settings/Radarr/index.tsx
+++ b/frontend/src/pages/Settings/Radarr/index.tsx
@@ -54,6 +54,11 @@ const SettingsRadarrView: FunctionComponent = () => {
+ values?.map((item) =>
+ item.replace(/[^a-z0-9_-]/gi, "").toLowerCase(),
+ )
+ }
>
Movies with those tags (case sensitive) in Radarr will be excluded
diff --git a/frontend/src/pages/Settings/Sonarr/index.tsx b/frontend/src/pages/Settings/Sonarr/index.tsx
index ed66ef679..ff4ac6ca2 100644
--- a/frontend/src/pages/Settings/Sonarr/index.tsx
+++ b/frontend/src/pages/Settings/Sonarr/index.tsx
@@ -56,6 +56,11 @@ const SettingsSonarrView: FunctionComponent = () => {
+ values?.map((item) =>
+ item.replace(/[^a-z0-9_-]/gi, "").toLowerCase(),
+ )
+ }
>
Episodes from series with those tags (case sensitive) in Sonarr will
diff --git a/frontend/src/pages/Settings/components/forms.tsx b/frontend/src/pages/Settings/components/forms.tsx
index 95134db92..1e4f744b9 100644
--- a/frontend/src/pages/Settings/components/forms.tsx
+++ b/frontend/src/pages/Settings/components/forms.tsx
@@ -160,13 +160,25 @@ export const Slider: FunctionComponent = (props) => {
};
type ChipsProp = BaseInput &
- Omit;
+ Omit & {
+ sanitizeFn?: (values: string[] | null) => string[] | undefined;
+ };
export const Chips: FunctionComponent = (props) => {
const { value, update, rest } = useBaseInput(props);
+ const handleChange = (value: string[] | null) => {
+ const sanitizedValues = props.sanitizeFn?.(value) ?? value;
+
+ update(sanitizedValues || null);
+ };
+
return (
-
+
);
};