jackwener/OpenCLI · error · CommandExecutionError
提交抖音上传失败,非 JSON 响应: HTTP ${res.status} ${text.slice(0, 300)}
Error message
提交抖音上传失败,非 JSON 响应: HTTP ${res.status} ${text.slice(0, 300)} What it means
commitVideoUploadInner POSTs CommitUploadInner and expects a JSON body; this error fires when JSON.parse fails on the response text, including the HTTP status and the first 300 characters of the raw body. It indicates the commit endpoint returned HTML, an empty body, or another non-JSON payload instead of the expected API envelope.
Source
Thrown at clis/douyin/_shared/vod-upload.js:193
const params = new URLSearchParams({
Action: 'CommitUploadInner',
Version: '2020-11-19',
SpaceName: VOD_SPACE_NAME,
});
const url = `${VOD_UPLOAD_HOST}?${params.toString()}`;
const body = JSON.stringify({ SessionKey: uploadInfo.session_key });
const headers = computeAws4Headers(url, credentials, {
method: 'POST',
body,
headers: { 'content-type': 'application/json;charset=UTF-8' },
});
const res = await fetch(url, { method: 'POST', headers, body, signal: AbortSignal.timeout(30000) });
const text = await res.text();
let payload;
try {
payload = JSON.parse(text);
} catch {
throw new CommandExecutionError(`提交抖音上传失败,非 JSON 响应: HTTP ${res.status} ${text.slice(0, 300)}`);
}
const error = payload?.ResponseMetadata?.Error;
if (!res.ok || error) {
throw new CommandExecutionError(`提交抖音上传失败: HTTP ${res.status} ${JSON.stringify(error ?? payload)}`);
}
const result = payload?.Result?.Results?.[0] ?? payload?.Result ?? {};
const videoId = result.Vid ?? result.VideoId ?? result.VideoID ?? result.vid ?? uploadInfo.video_id;
if (!videoId) {
throw new CommandExecutionError(`提交抖音上传响应缺少 video id: ${JSON.stringify(payload).slice(0, 500)}`);
}
const meta = result.Meta ?? result.VideoMeta ?? {};
return {
video_id: videoId,
poster_uri: result.PosterUri ?? result.PosterURI ?? result.SnapshotUri ?? result.SnapshotURI ?? '',
width: Number(meta.Width ?? meta.width ?? 720) || 720,
height: Number(meta.Height ?? meta.height ?? 1280) || 1280,
raw: result,
};View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the body snippet in the message — HTML suggests login/WAF issues; re-authenticate or complete verification and retry.
- Refresh STS credentials via getUploadAuthV5Credentials and re-run commit if the token expired.
- Retry with backoff for 5xx statuses — gateway failures are often transient.
- Bypass VPN/proxy to rule out response rewriting by middleboxes.
- Note that the upload itself may still have succeeded even if commit failed non-JSON; check the video id on the platform before re-uploading.
Example fix
// before
let payload;
try {
payload = JSON.parse(text);
} catch {
throw new CommandExecutionError(`提交抖音上传失败,非 JSON 响应: HTTP ${res.status} ${text.slice(0, 300)}`);
}
// after
let payload;
try {
payload = JSON.parse(text);
} catch {
if (res.status >= 500) return retryCommitWithBackoff(); // transient gateway failure
throw new CommandExecutionError(`提交抖音上传失败,非 JSON 响应: HTTP ${res.status} ${text.slice(0, 300)}`);
} Defensive patterns
Strategy: retry
Validate before calling
// refresh credentials if expired before committing
if (credentials.expired_time && credentials.expired_time * 1000 < Date.now()) {
credentials = await getUploadAuthV5Credentials(page);
} Type guard
null
Try / catch
try {
return await commitVideoUploadInner(uploadInfo, creds);
} catch (e) {
if (/非 JSON 响应/.test(e.message)) {
if (/HTTP 5\d\d/.test(e.message)) { await sleep(3000); return retry(); }
if (/<html/i.test(e.message)) throw new AuthRequiredError('creator.douyin.com', e.message);
}
throw e;
} Prevention
- Commit promptly after upload; expired tokens mid-flow cause edge errors.
- Retry transient 5xx with backoff before giving up.
- Check whether the video actually committed before re-uploading (commit may have succeeded server-side).
- Avoid VPN/proxy paths that can inject HTML error pages.
When it happens
Trigger: The CommitUploadInner fetch returns non-JSON: WAF/CAPTCHA HTML page, gateway 502/504 error page, empty body, or a redirect to login due to expired credentials.
Common situations: Expired STS token causing edge errors; risk-control interception of the commit request; transient CDN/edge failures; proxy/VPN middleboxes altering the response; Douyin endpoint changes.
Related errors
- 申请抖音上传地址失败,非 JSON 响应: HTTP ${res.status} ${text.slice(0, 300
- Boss API request failed: ${message}
- coingecko categories returned malformed JSON: ${err?.message
- Douyin API request failed (${method} ${url}): ${error instan
- 解析抖音上传授权失败: ${error instanceof Error ? error.message : Strin
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/80213d13a4db33c7.
Report an issue: GitHub.