{"record":{"id":"43d310741a3c73d4","repo":"jackwener/OpenCLI","slug":"creation-id-missing","errorCode":null,"errorMessage":"点击草稿按钮失败: creation-id-missing","messagePattern":"点击草稿按钮失败: creation-id-missing","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/douyin/draft.js","lineNumber":265,"sourceCode":"        stopPropagation() {},\n        nativeEvent: null,\n        target: btn,\n        currentTarget: btn,\n      });\n    } else {\n      btn.click();\n    }\n    return {\n      ok: true,\n      text: (btn.textContent || '').trim(),\n      creationId,\n    };\n  }`));\n    if (!result?.ok) {\n        throw new CommandExecutionError(`点击草稿按钮失败: ${result?.reason || 'unknown'}`);\n    }\n    if (!result.creationId) {\n        throw new CommandExecutionError('点击草稿按钮失败: creation-id-missing');\n    }\n    return {\n        text: result.text || '暂存离开',\n        creationId: result.creationId,\n    };\n}\n/**\n * Wait until creator center shows the resumable-draft prompt after saving.\n */\nasync function waitForDraftResult(page, creationId) {\n    let lastState = { href: '', bodyText: '' };\n    for (let attempt = 0; attempt < 20; attempt += 1) {\n        lastState = (await page.evaluate(`() => ({\n      href: location.href,\n      bodyText: document.body?.innerText || ''\n    })`));\n        if (lastState.href.includes('/creator-micro/content/upload')\n            && /继续编辑/.test(lastState.bodyText)) {","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/draft.js#L247-L283","documentation":"After clicking '暂存离开', clickSaveDraft walks the React fiber tree of the title input to read props.creation_id. If the click succeeded but no creation_id string was found on any fiber ancestor, it throws this CommandExecutionError with reason 'creation-id-missing'.","triggerScenarios":"Douyin moved creation_id off React fiber props (different state management, e.g. redux/store or URL only), the upload hadn't been assigned an id yet when saving very fast, or the title input's fiber root no longer carries the prop.","commonSituations":"Douyin frontend refactor changing where creation_id lives; saving immediately after upload before server assigns the id; internal React version change altering fiber key names ('__reactFiber$' prefix change).","solutions":["Retry with a slightly longer delay before saving (the id may not be assigned yet) — e.g. add a wait before clickSaveDraft","Check whether creation_id now appears in the page URL or global store; extract from there instead of the fiber walk","Update the fiber key prefix ('__reactFiber$') in clis/douyin/draft.js:223 if React internals changed"],"exampleFix":"// before: only fiber props\nif (typeof props?.creation_id === 'string' && props.creation_id) return props.creation_id;\n// after: fall back to URL\nconst fromUrl = new URLSearchParams(location.search).get('creation_id');\nreturn props?.creation_id || fromUrl || '';","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const r = await opencli.douyin.draft({ video, title });\n} catch (e) {\n  if (e.message.includes('creation-id-missing')) {\n    // retry with a longer pre-save delay so the server assigns creation_id\n  }\n}","preventionTips":["Add a short wait between form fill and save so the id gets assigned","Add URL/global-store fallbacks for creation_id extraction","Keep fiber-key prefixes ('__reactFiber$') current with the React version Douyin ships"],"tags":["douyin","react-fiber","draft-id","browser-automation"],"backgroundTag":"draft-id-missing","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}