{"record":{"id":"842858e0f4b4a4ed","repo":"siyuan-note/siyuan","slug":"remote-does-not-accept-credentials-in-the-url","errorCode":null,"errorMessage":"--remote does not accept credentials in the URL","messagePattern":"--remote does not accept credentials in the URL","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/electron/remoteKernel.js","lineNumber":19,"sourceCode":"const crypto = require(\"node:crypto\");\n\n// 解析命令行参数时保留值中的等号，避免 URL 查询参数被截断。\nconst getArgFrom = (args, name) => {\n    const prefix = name + \"=\";\n    const arg = args.find((item) => item === name || item.startsWith(prefix));\n    if (!arg) {\n        return;\n    }\n    return arg === name ? \"\" : arg.slice(prefix.length);\n};\n\nconst normalizeRemoteKernelOrigin = (value) => {\n    if (!value) {\n        throw new Error(\"--remote requires a URL\");\n    }\n    const url = new URL(value);\n    if (url.username || url.password) {\n        throw new Error(\"--remote does not accept credentials in the URL\");\n    }\n    if (url.pathname !== \"/\" || url.search || url.hash || value.includes(\"?\") || value.includes(\"#\")) {\n        throw new Error(\"--remote only accepts an origin without a path, query, or fragment\");\n    }\n    if (url.protocol !== \"https:\") {\n        throw new Error(\"--remote requires HTTPS\");\n    }\n    return url.origin;\n};\n\nconst insecureCertificateSwitchNames = Object.freeze([\n    \"allow-insecure-localhost\",\n    \"ignore-certificate-errors\",\n    \"ignore-certificate-errors-spki-list\",\n    \"ignore-ssl-errors\",\n    \"ignore-ssl-errors-with-hosts\",\n]);\nconst insecureCertificateSwitches = new Set(insecureCertificateSwitchNames);","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/app/electron/remoteKernel.js#L1-L37","documentation":"normalizeRemoteKernelOrigin rejects --remote URLs that embed credentials (user:pass@host). The remote kernel connection flow manages authentication via its own login/storage clearing, so baked-in URL credentials are not allowed.","triggerScenarios":"Calling normalizeRemoteKernelOrigin with a URL whose new URL(value) parse yields non-empty url.username or url.password — e.g. https://user:pass@host:6806 or https://user@host.","commonSituations":"Copy-pasting a URL from a reverse-proxy setup that uses HTTP basic auth; pasting credentials from a shared-link service; an old bookmark that included an inline token as the username.","solutions":["Strip the credentials and pass only the origin: https://host:6806","If basic-auth protection is in front of the kernel, handle auth at the proxy/VPN layer or expose the kernel origin without inline credentials","Use the app's own remote-kernel login screen for authentication instead of URL credentials","If a token is required, configure it where the kernel/proxy expects it (header/auth page), not in the URL"],"exampleFix":"// before\n//   --remote \"https://user:secret@myhost:6806\"\n// after\n//   --remote \"https://myhost:6806\"","handlingStrategy":"validation","validationCode":"const u = new URL(candidate);\nif (u.username || u.password) {\n  throw new Error(\"strip credentials from the --remote URL\");\n}","typeGuard":"const hasNoInlineCredentials = (v) => { try { const u = new URL(v); return !u.username && !u.password; } catch { return false; } };","tryCatchPattern":"try {\n  const origin = normalizeRemoteKernelOrigin(args.remote);\n} catch (e) {\n  if (e.message === \"--remote does not accept credentials in the URL\") {\n    // sanitize: new URL(v).origin and re-invoke, prompting for login in-app\n  }\n}","preventionTips":["Never paste URLs of the form user:pass@host into --remote","Handle proxy basic-auth outside the URL (VPN, proxy config, or the app's login screen)","Sanitize shared/bookmarked URLs down to origin before use"],"tags":["cli","url-validation","credentials","remote-kernel"],"backgroundTag":"invalid-argument-value","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}