siyuan-note/siyuan · error · Error

--remote only accepts an origin without a path, query, or fr

Error message

--remote only accepts an origin without a path, query, or fragment

What it means

normalizeRemoteKernelOrigin only accepts a bare origin. URLs containing a path, query string, or fragment are rejected so the app can deterministically append its own API and stage paths; anything after the host:port would break the constructed endpoints.

Source

Thrown at app/electron/remoteKernel.js:22

const getArgFrom = (args, name) => {
    const prefix = name + "=";
    const arg = args.find((item) => item === name || item.startsWith(prefix));
    if (!arg) {
        return;
    }
    return arg === name ? "" : arg.slice(prefix.length);
};

const normalizeRemoteKernelOrigin = (value) => {
    if (!value) {
        throw new Error("--remote requires a URL");
    }
    const url = new URL(value);
    if (url.username || url.password) {
        throw new Error("--remote does not accept credentials in the URL");
    }
    if (url.pathname !== "/" || url.search || url.hash || value.includes("?") || value.includes("#")) {
        throw new Error("--remote only accepts an origin without a path, query, or fragment");
    }
    if (url.protocol !== "https:") {
        throw new Error("--remote requires HTTPS");
    }
    return url.origin;
};

const insecureCertificateSwitchNames = Object.freeze([
    "allow-insecure-localhost",
    "ignore-certificate-errors",
    "ignore-certificate-errors-spki-list",
    "ignore-ssl-errors",
    "ignore-ssl-errors-with-hosts",
]);
const insecureCertificateSwitches = new Set(insecureCertificateSwitchNames);
const unsafeRemoteChromiumSwitchNames = Object.freeze([
    ...insecureCertificateSwitchNames,
    "allow-running-insecure-content",

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Trim the URL down to protocol://host:port before passing it to --remote
  2. If the kernel sits behind a subpath reverse proxy, expose a dedicated origin/subdomain for it instead
  3. Quote the URL in your shell to prevent ?, # from being interpreted
  4. Remove SSO/query parameters and complete any redirect login inside the app instead

Example fix

// before
//   --remote "https://myhost:6806/stage/build/app/"
// after
//   --remote "https://myhost:6806"
Defensive patterns

Strategy: validation

Validate before calling

const u = new URL(candidate);
if (u.pathname !== "/" || u.search || u.hash || candidate.includes("?") || candidate.includes("#")) {
  throw new Error("--remote accepts only protocol://host:port");
}

Type guard

const isBareOrigin = (v) => { try { const u = new URL(v); return u.pathname === "/" && !u.search && !u.hash; } catch { return false; } };

Try / catch

try {
  const origin = normalizeRemoteKernelOrigin(args.remote);
} catch (e) {
  if (e.message.startsWith("--remote only accepts an origin")) {
    // auto-trim: use new URL(v).origin and retry
  }
}

Prevention

When it happens

Trigger: A --remote value whose URL has pathname !== "/", or that contains "?" or "#" anywhere — e.g. https://host:6806/siyuan, https://host:6806/?x=1, or https://host:6806/#anchor.

Common situations: Pasting a full URL copied from a browser address bar including a path like /stage/build/app/; trailing path added by a shared link; query params added by SSO redirects; a stray # in a shell command due to unquoted input.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/c7f4a342eee9cf21. Report an issue: GitHub.