jackwener/OpenCLI · error · ArgumentError
Youdao Note URL must be under note.youdao.com or note.youdao
Error message
Youdao Note URL must be under note.youdao.com or note.youdao.cn
What it means
ArgumentError thrown by normalizeShareUrl when the URL hostname is not in ALLOWED_HOSTS (share.note.youdao.com, note.youdao.com, share.note.youdao.cn, note.youdao.cn). The extractor is written against Youdao's specific page structure, so arbitrary hosts would fail; the library rejects them up front.
Source
Thrown at clis/youdao/note.js:33
return payload;
}
function normalizeShareUrl(raw) {
const value = String(raw ?? '').trim();
if (!value) {
throw new ArgumentError('youdao note url cannot be empty', 'Pass a full public share URL from Youdao Notes.');
}
let parsed;
try {
parsed = new URL(value);
} catch {
throw new ArgumentError('Invalid Youdao Note URL', 'Example: https://share.note.youdao.com/ynoteshare/index.html?id=...&type=note');
}
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
throw new ArgumentError('Youdao Note URL must use http or https');
}
if (!ALLOWED_HOSTS.has(parsed.hostname)) {
throw new ArgumentError('Youdao Note URL must be under note.youdao.com or note.youdao.cn');
}
if (!parsed.searchParams.get('id')) {
throw new ArgumentError('Youdao Note URL must include an id query parameter');
}
const type = parsed.searchParams.get('type');
if (type && type !== 'note') {
throw new ArgumentError('youdao note only accepts shared note URLs', 'Shared notebooks are not implemented yet.');
}
return parsed.toString();
}
function formatYoudaoTimestamp(value) {
if (value == null || value === '') return '';
const numeric = Number(value);
if (!Number.isFinite(numeric) || numeric <= 0) return String(value);
const millis = numeric < 10_000_000_000 ? numeric * 1000 : numeric;
const date = new Date(millis);
if (Number.isNaN(date.getTime())) return String(value);View on GitHub (pinned to 49907e53dc)
Solutions
- Use a URL whose host is exactly share.note.youdao.com, note.youdao.com, share.note.youdao.cn, or note.youdao.cn
- Re-copy the share link via Youdao Notes' 'Share' feature, which always emits a share.note.youdao.com(/.cn) URL
- Fix typos in the hostname and drop any extra subdomains or suffixes
Example fix
// before
await youdaoNote('https://www.youdao.com/ynoteshare/index.html?id=abc');
// after
await youdaoNote('https://share.note.youdao.com/ynoteshare/index.html?id=abc'); Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = new Set(['share.note.youdao.com','note.youdao.com','share.note.youdao.cn','note.youdao.cn']);
function isYoudaoShareHost(u) {
try { return ALLOWED.has(new URL(u).hostname); } catch { return false; }
}
if (!isYoudaoShareHost(inputUrl)) throw new Error('URL must be a youdao note share link'); Type guard
function isYoudaoShareUrl(v) {
const hosts = ['share.note.youdao.com','note.youdao.com','share.note.youdao.cn','note.youdao.cn'];
try { return hosts.includes(new URL(v).hostname); } catch { return false; }
} Try / catch
try {
await youdaoNote(url);
} catch (e) {
if (String(e.message).includes('note.youdao.com or note.youdao.cn')) {
// re-copy the correct share.note.youdao.com link
} else throw e;
} Prevention
- Keep an allowlist check on hostname before invoking Youdao commands
- Always obtain share links from Youdao Notes' official Share dialog
- Watch for typos and spoofed suffix hosts like share.note.youdao.com.evil.io
When it happens
Trigger: Passing URLs from other domains (e.g. 'www.youdao.com/...', 'youdao.com', 'you.163.com', 'example.com/index.html?id=...') or a subdomain not in the allowlist such as 'share.note.youdao.com.evil.io'.
Common situations: Confusing Youdao's main site with its note-sharing host; using a translated/proxied mirror of the share page; typos in the domain (e.g. 'notes.youdao.com'); passing an entirely different notes service URL.
Related errors
- lang must be one of: ${[...ALLOWED_LANGS].join(', ')}
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
- archive search limit must be <= 100
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/534a59387d85a264.
Report an issue: GitHub.