{"record":{"id":"d1e4cb9b8397dec9","repo":"jackwener/OpenCLI","slug":"sessionkey","errorCode":null,"errorMessage":"抖音上传提交缺少 SessionKey","messagePattern":"抖音上传提交缺少 SessionKey","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/douyin/_shared/vod-upload.js","lineNumber":173,"sourceCode":"  const videoId = payload?.Result?.Vid || uploadNode?.Vid;\n  const sessionKey = uploadNode?.SessionKey ?? storeInfo?.SessionKey ?? payload?.Result?.SessionKey;\n  if (!uploadNode?.UploadHost || !storeInfo?.StoreUri || !storeInfo?.Auth || !videoId || !sessionKey) {\n    throw new CommandExecutionError(`申请抖音上传地址响应缺少必要字段: ${JSON.stringify(payload).slice(0, 500)}`);\n  }\n  return {\n    video_id: videoId,\n    tos_upload_url: `https://${uploadNode.UploadHost}/${storeInfo.StoreUri}`,\n    auth: storeInfo.Auth,\n    session_key: sessionKey,\n    upload_header: uploadNode.UploadHeader ?? {},\n    user_id: credentials.user_id ?? '',\n  };\n}\n\n\nexport async function commitVideoUploadInner(uploadInfo, credentials) {\n  if (!uploadInfo?.session_key) {\n    throw new CommandExecutionError('抖音上传提交缺少 SessionKey');\n  }\n  const params = new URLSearchParams({\n    Action: 'CommitUploadInner',\n    Version: '2020-11-19',\n    SpaceName: VOD_SPACE_NAME,\n  });\n  const url = `${VOD_UPLOAD_HOST}?${params.toString()}`;\n  const body = JSON.stringify({ SessionKey: uploadInfo.session_key });\n  const headers = computeAws4Headers(url, credentials, {\n    method: 'POST',\n    body,\n    headers: { 'content-type': 'application/json;charset=UTF-8' },\n  });\n  const res = await fetch(url, { method: 'POST', headers, body, signal: AbortSignal.timeout(30000) });\n  const text = await res.text();\n  let payload;\n  try {\n    payload = JSON.parse(text);","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/_shared/vod-upload.js#L155-L191","documentation":"commitVideoUploadInner requires uploadInfo.session_key to commit the finished upload via CommitUploadInner; this guard throws when session_key is missing/empty on the uploadInfo object. Without SessionKey the server cannot correlate the committed upload, so the library fails before making the network call.","triggerScenarios":"Calling commitVideoUploadInner with an uploadInfo object that lacks session_key — e.g. it was built manually, or came from a code path that skipped/failed applyVideoUploadInner's field extraction, or the property was renamed.","commonSituations":"Custom pipeline code constructing uploadInfo by hand and forgetting session_key; downstream code destructuring applyVideoUploadInner's return and dropping fields; an earlier 'missing required fields' error handled loosely, letting a partial object flow through.","solutions":["Ensure uploadInfo is the full object returned by applyVideoUploadInner, which always sets session_key.","Log the uploadInfo keys before committing to see which fields are missing.","Fix upstream code that reconstructs or filters uploadInfo and accidentally drops session_key.","If applyVideoUploadInner threw earlier, abort the pipeline instead of committing with a partial object.","Add your own precondition check on uploadInfo.session_key before calling commit."],"exampleFix":"// before\nawait commitVideoUploadInner({ video_id: vid }, credentials); // missing session_key\n// after\nconst uploadInfo = await applyVideoUploadInner(fileSize, credentials); // full object incl. session_key\nawait commitVideoUploadInner(uploadInfo, credentials);","handlingStrategy":"validation","validationCode":"function isCommittable(uploadInfo) {\n  return Boolean(uploadInfo && typeof uploadInfo.session_key === 'string' && uploadInfo.session_key.length > 0);\n}\n// before committing:\nif (!isCommittable(uploadInfo)) throw new Error('uploadInfo 缺少 session_key，请检查 apply 阶段结果');","typeGuard":"null","tryCatchPattern":"try {\n  await commitVideoUploadInner(uploadInfo, creds);\n} catch (e) {\n  if (/缺少 SessionKey/.test(e.message)) {\n    console.error('uploadInfo keys:', Object.keys(uploadInfo ?? {}));\n  }\n  throw e;\n}","preventionTips":["Always pass the object returned by applyVideoUploadInner directly to commit — never hand-build uploadInfo.","Validate session_key immediately after apply, not at commit time.","If apply threw, skip commit rather than committing a partial object.","Type your uploadInfo so TypeScript flags missing session_key at the call site."],"tags":["douyin","validation","missing-field","commit-upload"],"backgroundTag":"missing-required-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}