{"record":{"id":"7f44ee18830a16a1","repo":"jackwener/OpenCLI","slug":"json-stringify-result-7f44ee","errorCode":null,"errorMessage":"抖音后台管理删除失败: ${JSON.stringify(result)}","messagePattern":"抖音后台管理删除失败: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/douyin/delete.js","lineNumber":98,"sourceCode":"          if (!confirmButton) return { ok: false, reason: 'confirm_button_not_found', aweme_id: target.item.aweme_id, item_id: target.item.item_id };\n          confirmButton.click();\n          for (let wait = 0; wait < 20; wait += 1) {\n            await sleep(500);\n            const after = await loadTarget();\n            if (!after.ok && after.reason === 'not_found') {\n              return { ok: true, aweme_id: target.item.aweme_id, item_id: target.item.item_id, title: target.title };\n            }\n          }\n          return { ok: false, reason: 'delete_not_confirmed', aweme_id: target.item.aweme_id, item_id: target.item.item_id };\n        }\n        await sleep(500);\n      }\n      return { ok: false, reason: 'card_not_found', aweme_id: target.item.aweme_id, item_id: target.item.item_id, index: target.index, listCount: target.listCount };\n    })()\n  `), '抖音后台管理删除响应异常');\n\n    if (!result?.ok) {\n        throw new CommandExecutionError(`抖音后台管理删除失败: ${JSON.stringify(result)}`);\n    }\n    return result;\n}\n\nasync function findWorkListItem(page, workId) {\n    const data = await browserFetch(page, 'GET', `https://creator.douyin.com${WORK_LIST_URL}`, { timeoutMs: 8000 });\n    const list = data.data?.work_list ?? data.aweme_list ?? data.work_list ?? [];\n    if (!Array.isArray(list)) {\n        throw new CommandExecutionError('抖音作品列表响应缺少 work_list/aweme_list');\n    }\n    return list.find((entry) => String(entry.aweme_id || '') === workId || String(entry.item_id || '') === workId) || null;\n}\n\ncli({\n    site: 'douyin',\n    name: 'delete',\n    access: 'write',\n    description: '删除作品（优先使用创作者后台作品管理；找不到时回退到旧删除接口）',","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/delete.js#L80-L116","documentation":"Thrown by deleteViaCreatorManage when an in-page delete via the creator-micro content manage UI returns a result object whose ok flag is falsy (e.g. card_not_found). The library runs injected page JS to click the delete card and requires an explicit ok:true. The message embeds the whole result (reason, aweme_id, index, listCount) for diagnosis.","triggerScenarios":"The target work's card was not found in the manage list (reason 'card_not_found'); the work was already deleted before the call; the manage list is paginated/filtered so the target is not on the first page; DOM selectors changed after a Douyin frontend update so the injected script fails.","commonSituations":"Deleting a video that was removed manually or by Douyin moderation between lookup and delete; account with many works where the item sits beyond the loaded list (count=20); Douyin UI redesign breaking selectors.","solutions":["Read result.reason in the message: if card_not_found, confirm the work still exists on the manage page","Use the API delete path (aweme/delete endpoint) instead of the UI-manage path if selectors broke","Load more items or adjust WORK_LIST_URL status/count params if the item is beyond the first page","Update injected selectors after a Douyin frontend change"],"exampleFix":"// before: rely on UI manage path\nawait deleteViaCreatorManage(page, awemeId);\n// after: fall back to API delete when card is missing\ntry { await deleteViaCreatorManage(page, awemeId); }\ncatch (e) { if (String(e).includes('card_not_found')) await deleteViaApi(page, awemeId); else throw e; }","handlingStrategy":"fallback","validationCode":"// confirm the work exists in the manage list before invoking UI delete\nconst item = await findWorkListItem(page, awemeId);\nif (!item) throw new Error(`${awemeId} not in work list; skip UI delete`);","typeGuard":"function isDeleteResultOk(result) {\n  return Boolean(result && result.ok === true);\n}","tryCatchPattern":"try {\n  await deleteViaCreatorManage(page, awemeId);\n} catch (e) {\n  if (String(e).includes('card_not_found')) {\n    return deleteViaAwemeDeleteApi(page, awemeId); // API fallback\n  } throw e;\n}","preventionTips":["Pre-check that the work appears in the work list before UI automation","Watch for Douyin frontend redesigns and update selectors","Handle already-deleted works as success/no-op","Fall back to the aweme/delete API when UI automation fails"],"tags":["douyin","delete","ui-automation","page-script"],"backgroundTag":"ui-automation-action-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}