jackwener/OpenCLI · error · CommandExecutionError

提交抖音上传失败: HTTP ${res.status} ${JSON.stringify(error ?? paylo

Error message

提交抖音上传失败: HTTP ${res.status} ${JSON.stringify(error ?? payload)}

What it means

Thrown by commitVideoUploadInner after calling the Douyin VOD CommitUploadInner API when the HTTP response is not OK or the JSON payload contains ResponseMetadata.Error. It wraps the full API error object so the developer can see why the commit failed (signature, session, or space problems). The library throws it because a non-ok commit means the uploaded video will never become a playable Vid.

Source

Thrown at clis/douyin/_shared/vod-upload.js:197

  });
  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

  1. Inspect the embedded ResponseMetadata.Error.Code in the message and match it against VodSpace/InvalidParameter errors
  2. Re-run the upload from scratch to get a fresh SessionKey and commit promptly
  3. Verify VOD access key/secret and VOD_SPACE_NAME env/config values
  4. Check system clock skew if signature-related errors appear
  5. Retry after a short delay if the status is 5xx/rate-limit

Example fix

// before: commit long after upload finished, session expired
await uploadChunks(...); await sleep(600000); await commitVideoUploadInner(info, creds);
// after: commit immediately after upload
await uploadChunks(...);
const result = await commitVideoUploadInner(info, creds);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!process.env.VOD_ACCESS_KEY || !process.env.VOD_SECRET_KEY) throw new Error('VOD credentials missing');
if (!uploadInfo?.session_key) throw new Error('session_key missing; re-run upload');

Type guard

function isVodError(payload) {
  return Boolean(payload?.ResponseMetadata?.Error);
}

Try / catch

try {
  const committed = await commitVideoUploadInner(info, creds);
} catch (e) {
  if (/提交抖音上传失败/.test(e.message)) {
    console.error('commit rejected:', e.message);
    // re-upload + retry once with fresh session
  } else throw e;
}

Prevention

When it happens

Trigger: Calling commitVideoUploadInner with an expired/invalid SessionKey; wrong AWS4 credentials (access key/secret) so the VOD API rejects signature; VOD_SPACE_NAME not existing or unauthorized; the chunked upload never completed so CommitUploadInner rejects the session; transient VOD 5xx responses.

Common situations: Expired Volcano/ByteDance VOD credentials in env config; uploading a file then committing after session timeout; misconfigured space name after a Douyin backend change; clock skew invalidating AWS4 signature.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/83acc4a331d78ae5. Report an issue: GitHub.