diff --git a/components/common/ServerUrlField.tsx b/components/common/ServerUrlField.tsx
index e8fa6b5fe..122cd8afb 100644
--- a/components/common/ServerUrlField.tsx
+++ b/components/common/ServerUrlField.tsx
@@ -18,8 +18,6 @@ interface ServerUrlFieldProps {
label?: string;
hint?: string;
placeholder?: string;
- /** Shown in the "version too low" message. */
- minVersion?: string;
editable?: boolean;
resolveOptions?: ResolveOptions;
}
@@ -38,7 +36,6 @@ export function ServerUrlField({
label,
hint,
placeholder,
- minVersion,
editable = true,
resolveOptions,
}: ServerUrlFieldProps) {
@@ -96,11 +93,7 @@ export function ServerUrlField({
clearButtonMode='never'
/>
-
+
);
}
diff --git a/components/common/ServerUrlStatusText.tsx b/components/common/ServerUrlStatusText.tsx
index 13c521272..e402289d6 100644
--- a/components/common/ServerUrlStatusText.tsx
+++ b/components/common/ServerUrlStatusText.tsx
@@ -10,11 +10,9 @@ import { Text } from "./Text";
*/
export function ServerUrlStatusText({
state,
- minVersion,
className = "",
}: {
state: ServerUrlResolverState;
- minVersion?: string;
className?: string;
}) {
const { t } = useTranslation();
@@ -41,16 +39,11 @@ export function ServerUrlStatusText({
}
const message =
- state.reason === "version-too-low"
- ? t("server_url.version_too_low", {
- version: state.version ?? "?",
- min: minVersion ?? "",
- })
- : state.reason === "wrong-service"
- ? t("server_url.wrong_service")
- : state.reason === "invalid"
- ? t("server_url.invalid_url")
- : t("server_url.unreachable");
+ state.reason === "wrong-service"
+ ? t("server_url.wrong_service")
+ : state.reason === "invalid"
+ ? t("server_url.invalid_url")
+ : t("server_url.unreachable");
return {message};
}
diff --git a/components/settings/Jellyseerr.tsx b/components/settings/Jellyseerr.tsx
index e0f65b0de..1129830c2 100644
--- a/components/settings/Jellyseerr.tsx
+++ b/components/settings/Jellyseerr.tsx
@@ -146,7 +146,6 @@ export const JellyseerrSettings = () => {
onChangeText={setjellyseerrServerUrl}
onResolved={(url) => setResolvedUrl(url)}
probe={jellyseerrProbe}
- minVersion='2.0.0'
label={t("home.settings.plugins.jellyseerr.server_url")}
hint={t("home.settings.plugins.jellyseerr.server_url_hint")}
placeholder={t(
diff --git a/hooks/useJellyseerr.ts b/hooks/useJellyseerr.ts
index 4ae918d85..32c7b6c25 100644
--- a/hooks/useJellyseerr.ts
+++ b/hooks/useJellyseerr.ts
@@ -48,6 +48,7 @@ import type {
TvDetails,
} from "@/utils/jellyseerr/server/models/Tv";
import { writeErrorLog } from "@/utils/log";
+import { isVersionBelow } from "@/utils/serverUrl/semver";
interface SearchParams {
query: string;
@@ -141,10 +142,13 @@ export class JellyseerrApi {
.then((response) => {
const { status, headers, data } = response;
if (inRange(status, 200, 299)) {
- if (data.version < "2.0.0") {
+ if (data.version && isVersionBelow(data.version, "2.0.0")) {
const error = t(
"jellyseerr.toasts.jellyseer_does_not_meet_requirements",
);
+ writeErrorLog(
+ `Jellyseerr version ${data.version} is below the required 2.0.0`,
+ );
toast.error(error);
throw Error(error);
}
diff --git a/hooks/useServerUrlResolver.ts b/hooks/useServerUrlResolver.ts
index 736fa978e..2ef7aa9f9 100644
--- a/hooks/useServerUrlResolver.ts
+++ b/hooks/useServerUrlResolver.ts
@@ -11,7 +11,7 @@ export type ServerUrlResolverState =
| { status: "idle" }
| { status: "resolving" }
| { status: "ok"; resolvedUrl: string; meta?: Record }
- | { status: "error"; reason: ResolveFailureReason; version?: string };
+ | { status: "error"; reason: ResolveFailureReason };
/**
* Stateful wrapper around `resolveServerUrl` for screens.
@@ -46,11 +46,7 @@ export function useServerUrlResolver(
setState(
result.ok
? { status: "ok", resolvedUrl: result.url, meta: result.meta }
- : {
- status: "error",
- reason: result.reason,
- version: result.version,
- },
+ : { status: "error", reason: result.reason },
);
}
return result;
diff --git a/translations/en.json b/translations/en.json
index 0e8571e75..7b4c6adaf 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -5,7 +5,6 @@
"connected": "Connected to {{url}}",
"unreachable": "Server unreachable",
"wrong_service": "Reachable, but not the expected server",
- "version_too_low": "Version {{version}} is too old (minimum {{min}})",
"invalid_url": "Enter a valid address"
},
"login": {
diff --git a/utils/serverUrl/probes/jellyseerr.ts b/utils/serverUrl/probes/jellyseerr.ts
index cf4ba20e8..5b01050bf 100644
--- a/utils/serverUrl/probes/jellyseerr.ts
+++ b/utils/serverUrl/probes/jellyseerr.ts
@@ -1,14 +1,11 @@
import axios from "axios";
-import { isVersionBelow } from "../semver";
import type { ServerProbe } from "../types";
-/** Jellyseerr/Overseerr minimum supported version. */
-const MIN_VERSION = "2.0.0";
-
/**
* Probe for a Jellyseerr server. `/api/v1/status` is jellyseerr/overseerr
- * specific and unauthenticated, so it both proves reachability and confirms
- * we hit the right service.
+ * specific and unauthenticated, so it both proves reachability and confirms we
+ * hit the right service. The minimum-version requirement is enforced at login
+ * time (see JellyseerrApi.test) — not surfaced here, to keep the field UI clean.
*/
export const jellyseerrProbe: ServerProbe = async (url, signal) => {
try {
@@ -19,22 +16,14 @@ export const jellyseerrProbe: ServerProbe = async (url, signal) => {
if (status < 200 || status >= 300) return { status: "unreachable" };
- const version: string | undefined =
- typeof data?.version === "string" ? data.version : undefined;
-
// A JSON body carrying version/commitTag identifies a real jellyseerr.
- if (
- !version &&
- !(data && typeof data === "object" && "commitTag" in data)
- ) {
- return { status: "wrong-service" };
- }
+ const looksLikeJellyseerr =
+ !!data &&
+ typeof data === "object" &&
+ (typeof data.version === "string" || "commitTag" in data);
+ if (!looksLikeJellyseerr) return { status: "wrong-service" };
- if (version && isVersionBelow(version, MIN_VERSION)) {
- return { status: "version-too-low", version };
- }
-
- return { status: "ok", meta: { version } };
+ return { status: "ok", meta: { version: data.version } };
} catch {
return { status: "unreachable" };
}
diff --git a/utils/serverUrl/resolve.ts b/utils/serverUrl/resolve.ts
index 8cf5b234b..8fa270140 100644
--- a/utils/serverUrl/resolve.ts
+++ b/utils/serverUrl/resolve.ts
@@ -4,13 +4,12 @@ import type { ServerProbe, ServerProbeOutcome } from "./types";
export type ResolveFailureReason =
| "empty"
| "invalid"
- | "version-too-low"
| "wrong-service"
| "unreachable";
export type ResolveResult =
| { ok: true; url: string; meta?: Record }
- | { ok: false; reason: ResolveFailureReason; version?: string };
+ | { ok: false; reason: ResolveFailureReason };
export interface ResolveOptions {
/** Per-candidate probe timeout in ms. Default 5000. */
@@ -22,7 +21,6 @@ export interface ResolveOptions {
// Order in which to surface a failure when no candidate validated:
// the more specific/actionable the reason, the earlier it is reported.
const FAILURE_PRIORITY = [
- "version-too-low",
"wrong-service",
"unreachable",
] as const satisfies ReadonlyArray;
@@ -62,11 +60,7 @@ export async function resolveServerUrl(
for (const reason of FAILURE_PRIORITY) {
const hit = outcomes.find((outcome) => outcome.status === reason);
if (hit) {
- return {
- ok: false,
- reason,
- version: hit.status === "version-too-low" ? hit.version : undefined,
- };
+ return { ok: false, reason };
}
}
return { ok: false, reason: "unreachable" };
diff --git a/utils/serverUrl/types.ts b/utils/serverUrl/types.ts
index f95658924..45fd4985f 100644
--- a/utils/serverUrl/types.ts
+++ b/utils/serverUrl/types.ts
@@ -1,7 +1,6 @@
/** Result of probing a single candidate URL for a specific service. */
export type ServerProbeOutcome =
| { status: "ok"; meta?: Record }
- | { status: "version-too-low"; version?: string }
| { status: "wrong-service" }
| { status: "unreachable" };