{"record":{"id":"4aa1a1df391ebc8e","repo":"jackwener/OpenCLI","slug":"invalid-youdao-note-url","errorCode":null,"errorMessage":"Invalid Youdao Note URL","messagePattern":"Invalid Youdao Note URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/youdao/note.js","lineNumber":27,"sourceCode":"]);\n\nfunction unwrapEvaluateResult(payload) {\n  if (payload && !Array.isArray(payload) && typeof payload === 'object' && 'session' in payload && 'data' in payload) {\n    return payload.data;\n  }\n  return payload;\n}\n\nfunction normalizeShareUrl(raw) {\n  const value = String(raw ?? '').trim();\n  if (!value) {\n    throw new ArgumentError('youdao note url cannot be empty', 'Pass a full public share URL from Youdao Notes.');\n  }\n  let parsed;\n  try {\n    parsed = new URL(value);\n  } catch {\n    throw new ArgumentError('Invalid Youdao Note URL', 'Example: https://share.note.youdao.com/ynoteshare/index.html?id=...&type=note');\n  }\n  if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\n    throw new ArgumentError('Youdao Note URL must use http or https');\n  }\n  if (!ALLOWED_HOSTS.has(parsed.hostname)) {\n    throw new ArgumentError('Youdao Note URL must be under note.youdao.com or note.youdao.cn');\n  }\n  if (!parsed.searchParams.get('id')) {\n    throw new ArgumentError('Youdao Note URL must include an id query parameter');\n  }\n  const type = parsed.searchParams.get('type');\n  if (type && type !== 'note') {\n    throw new ArgumentError('youdao note only accepts shared note URLs', 'Shared notebooks are not implemented yet.');\n  }\n  return parsed.toString();\n}\n\nfunction formatYoudaoTimestamp(value) {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youdao/note.js#L9-L45","documentation":"ArgumentError thrown by normalizeShareUrl when the supplied string cannot be parsed by the URL constructor (new URL(value) throws). The library needs an absolute, well-formed URL to hand to page.goto, so malformed input is rejected immediately.","triggerScenarios":"Passing values like 'share.note.youdao.com/ynoteshare/...' (no scheme), 'not a url', a bare note id, a URL with invalid characters/spaces, or a truncated copy-pasted link to `youdao note <url>`.","commonSituations":"Users pasting a relative path or just the query string; URLs mangled by shell quoting or markdown trimming; note IDs from email links pasted without the domain; scheme-less URLs from JSON configs.","solutions":["Prefix the scheme if missing: prepend 'https://' when the value starts with 'share.note.youdao' or 'note.youdao'","Trim whitespace and re-copy the full URL from the browser address bar","URL-encode or strip characters that break URL parsing (spaces, unescaped quotes)"],"exampleFix":"// before\nconst url = 'share.note.youdao.com/ynoteshare/index.html?id=abc';\nawait youdaoNote(url);\n// after\nconst raw = 'share.note.youdao.com/ynoteshare/index.html?id=abc';\nconst url = raw.startsWith('http') ? raw : `https://${raw}`;\nawait youdaoNote(url);","handlingStrategy":"validation","validationCode":"function isParseableUrl(u) {\n  try { new URL(u); return true; } catch { return false; }\n}\nif (!isParseableUrl(inputUrl)) inputUrl = `https://${inputUrl}`;","typeGuard":"function isAbsoluteUrl(v) {\n  if (typeof v !== 'string') return false;\n  try { return Boolean(new URL(v)); } catch { return false; }\n}","tryCatchPattern":"try {\n  await youdaoNote(url);\n} catch (e) {\n  if (String(e.message).includes('Invalid Youdao Note URL')) {\n    // show the expected format: https://share.note.youdao.com/ynoteshare/index.html?id=...&type=note\n  } else throw e;\n}","preventionTips":["Pre-parse input with new URL() before calling the command","Auto-prepend 'https://' for scheme-less hosts","Trim and re-encode URLs coming from copy/paste or shell arguments"],"tags":["argument-error","url-parsing","validation","malformed-input"],"backgroundTag":"invalid-url-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}