jackwener/OpenCLI · error · CommandExecutionError
${label} returned a malformed string
Error message
${label} returned a malformed string What it means
readOptionalString validates that an optional string field is null/undefined or a string; anything else throws this CommandExecutionError. It is used by the redirectUrl accessor of the bilibili video command.
Source
Thrown at clis/bilibili/video.js:29
function unwrapBrowserResult(value) {
if (value && typeof value === 'object' && typeof value.session === 'string' && Object.hasOwn(value, 'data')) {
return value.data;
}
return value;
}
function readOptionalFlag(value, label) {
if (value == null) return false;
if (typeof value === 'boolean') return value;
if (typeof value === 'number') return value !== 0;
throw new CommandExecutionError(`${label} returned a malformed flag`);
}
function readOptionalString(value, label) {
if (value == null) return '';
if (typeof value === 'string') return value;
throw new CommandExecutionError(`${label} returned a malformed string`);
}
cli({
site: 'bilibili',
name: 'video',
access: 'read',
description: 'Get Bilibili video metadata (title, author, duration, stats, etc.)',
strategy: Strategy.COOKIE,
args: [
{ name: 'bvid', required: true, positional: true, help: 'BV ID, video URL, or b23.tv short link' },
{ name: 'page', required: false, help: '分P 选集序号(从 1 开始)。多 P 视频指定某一集,title/cid 返回该集;缺省取整集默认(P1)' },
],
columns: ['field', 'value'],
func: async (page, kwargs) => {
if (!page) {
throw new CommandExecutionError('Browser session required for bilibili video');
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Log the raw value for the failing video to see the unexpected type
- Coerce safe cases (e.g. String(value)) if the field is reliably scalar
- Catch the error and return '' for redirect_url so the rest of the output still renders
- Update the field handling in clis/bilibili/video.js if the API schema changed
Example fix
// before
if (typeof value === 'string') return value;
throw new CommandExecutionError(`${label} returned a malformed string`);
// after
if (typeof value === 'string') return value;
if (typeof value === 'number') return String(value);
throw new CommandExecutionError(`${label} returned a malformed string`); Defensive patterns
Strategy: type-guard
Validate before calling
null
Type guard
function isOptionalString(v) {
return v == null || typeof v === 'string';
} Try / catch
try { const info = await getVideoInfo(bvid); }
catch (e) {
if (e instanceof CommandExecutionError && e.message.includes('malformed string')) { console.warn('redirect_url had unexpected type'); }
else throw e;
} Prevention
- Never assume string fields are always strings in scraped payloads
- Coerce scalars defensively at the parsing boundary
- Regression-test against captured real payloads
- Handle deleted/locked videos where fields may become structured errors
When it happens
Trigger: The video API's redirect_url (or similar string field) arrives as a number, object, or array instead of a string — schema drift or an unusual video entry shape.
Common situations: Bilibili changing a field's type; certain videos (deleted, region-locked) returning structured error objects where a string is expected; middleware JSON transformations.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${label} returned a malformed flag
- Cannot resolve aid for bvid: ${bvid}
- Bilibili creator comparison returned malformed metric ${defi
- Bilibili view API returned a malformed payload during paid-c
- 获取视频分P信息失败: ${error?.message || error}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d26d7df255bc64e8.
Report an issue: GitHub.