diegosouzapw/OmniRoute · error · Error

detail

Error message

detail

What it means

Shared apiCall() guard in the Redis launcher panel: every /api/local/redis<endpoint> request that returns non-ok builds a 'detail' message — the JSON body's error field when parseable, otherwise the raw 'HTTP <status>' sentinel — and throws it. The thrown value simply reports why the Redis control action (start/stop/status/config) was rejected; it carries no Redis-specific semantics of its own.

Solutions

  1. Check the Redis service status card: the control panel calls /api/local/redis endpoints, so verify the embedded Redis service is actually running before retrying the operation.
  2. Inspect the error detail: apiCall prefers the JSON body's error field over the raw 'HTTP <status>' string, which usually names the failing action (start/stop/config) directly.
  3. If the status is 5xx, check server logs for the Redis child process failing to spawn (port conflict, missing binary, permission issue on the data directory).
  4. Retry the action after the service settles — start/stop races can produce transient 409/503 responses from the local Redis controller.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/app/(dashboard)/dashboard/settings/components/RedisLauncherPanel.tsx:32 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25). Data as JSON: /api/errors/1b4a92b0655c51c2. Report an issue: GitHub.

Appendix: source

Thrown at src/app/(dashboard)/dashboard/settings/components/RedisLauncherPanel.tsx:32

  detail?: string;
};

async function apiCall(endpoint: string, options: RequestInit = {}) {
  const res = await fetch(`/api/local/redis${endpoint}`, {
    method: options.method || "GET",
    headers: { "Content-Type": "application/json" },
    body: options.body,
    cache: "no-store",
  });
  if (!res.ok) {
    let detail = `HTTP ${res.status}`;
    try {
      const json = await res.json();
      if (json?.error) detail = json.error;
    } catch {
      // ignore
    }
    throw new Error(detail);
  }
  return res.json();
}

/**
 * Compact 1-click Redis control. Sits inside the resilience settings tab and
 * shells out to the same logic exposed via the `omniroute redis` CLI command.
 * The actual container management is delegated to the server-side endpoint
 * at /api/local/redis/* so the browser never executes podman/docker directly.
 */
export default function RedisLauncherPanel() {
  const t = useTranslations("settings");
  const [state, setState] = useState<LaunchState>("idle");
  const [status, setStatus] = useState<Status | null>(null);
  const [error, setError] = useState<string | null>(null);

  async function refresh() {
    setState("checking");

View on GitHub (pinned to a179ffed5b)