jackwener/OpenCLI · error · ArgumentError
book URL must be a https://weread.qq.com/web/reader/<id> URL
Error message
book URL must be a https://weread.qq.com/web/reader/<id> URL
What it means
resolveBookTarget throws this ArgumentError when the target looks like a URL (matches /^https?:\/\//i) but parseWereadReaderUrl cannot normalize it to a https://weread.qq.com/web/reader/<id> URL. parseWereadReaderUrl rejects non-https schemes, other hostnames, wrong path shape, or extra path segments.
Source
Thrown at clis/weread/book-search.js:254
chapters: [],
};
if (!selected.bookId) {
throw new CommandExecutionError(`WeRead book search result ${bookRank} is missing bookId`);
}
const htmlEntries = await loadSearchHtmlEntries(bookQuery);
selected.readerUrl = resolveReaderUrlForBook(selected, htmlEntries);
const readerMetadata = await loadReaderMetadata(selected.readerUrl);
return {
...selected,
...Object.fromEntries(Object.entries(readerMetadata ?? {}).filter(([, value]) => value != null && value !== '' && !(Array.isArray(value) && value.length === 0))),
};
}
async function resolveBookTarget(target, bookRank) {
if (/^https?:\/\//i.test(target)) {
const readerUrl = parseWereadReaderUrl(target);
if (!readerUrl) {
throw new ArgumentError('book URL must be a https://weread.qq.com/web/reader/<id> URL');
}
const metadata = await loadReaderMetadata(readerUrl);
if (!metadata?.bookId) {
throw new CommandExecutionError('Could not parse a bookId from the reader URL');
}
return metadata;
}
if (/^\d+$/.test(target)) {
const metadata = {};
metadata.bookId = target;
metadata.title = '';
metadata.author = '';
metadata.readerUrl = '';
metadata.chapters = [];
return metadata;
}
return searchBookByQuery(target, bookRank);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Open the book in the WeRead web reader and copy the full https://weread.qq.com/web/reader/<id> URL from the address bar.
- Or pass the numeric bookId directly instead of a URL.
- Convert http:// to https:// and remove extra path segments/query params before calling.
Example fix
// before
resolveBookTarget('http://weread.qq.com/web/bookDetail/abc', 1)
// after
resolveBookTarget('https://weread.qq.com/web/reader/abc', 1) Defensive patterns
Strategy: validation
Validate before calling
function isWereadReaderUrl(u) {
try {
const url = new URL(u);
const parts = url.pathname.split('/').filter(Boolean);
return url.protocol === 'https:' && url.hostname === 'weread.qq.com' &&
parts[0] === 'web' && parts[1] === 'reader' && parts.length === 3 && !!parts[2];
} catch { return false; }
}
if (!isWereadReaderUrl(target)) throw new Error('not a weread reader URL'); Type guard
function isWereadReaderUrl(u) {
return /^https:\/\/weread\.qq\.com\/web\/reader\/[^/?#]+$/.test(u);
} Prevention
- Copy URLs only from the web reader address bar (https://weread.qq.com/web/reader/<id>).
- Convert http:// to https:// and strip query/hash before passing.
- Pass numeric bookId when you have it.
When it happens
Trigger: Passing a weread URL that is not a reader URL (e.g. https://weread.qq.com/web/bookDetail/xxx), an http:// URL, a mobile weread.qq.com/share/ link, or a reader URL with query/extra path segments.
Common situations: Copying a book detail or share link from the WeRead app instead of the web reader URL; stripping the hash fragment that apps put in reader URLs; shortening the URL.
Related errors
- 1688 item expects an offer URL or offer ID
- Invalid 1688 store URL
- Invalid 1688 URL
- Expected an exact BVID or bilibili.com video URL, for exampl
- Expected a trusted HTTPS bilibili.com video URL without cred
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/99fa26cc9e3a528d.
Report an issue: GitHub.