{"record":{"id":"a0cd790a79bf1269","repo":"jackwener/OpenCLI","slug":"wechat-article-editor-did-not-load-the-session-ma","errorCode":null,"errorMessage":"WeChat article editor did not load. The session may have expired.","messagePattern":"WeChat article editor did not load\\. The session may have expired\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/weixin/create-draft.js","lineNumber":65,"sourceCode":"    const mimeType = IMAGE_MIME_TYPES.get(extension);\n    if (!mimeType) {\n        throw new ArgumentError('weixin create-draft cover-image must be JPEG, PNG, GIF, or WebP');\n    }\n    return { absPath, fileName: path.basename(absPath), mimeType };\n}\n\nasync function navigateToEditor(page) {\n    await page.goto(WEIXIN_HOME);\n    await page.wait(3);\n    const token = await evaluate(page, `(window.location.href.match(/token=(\\\\d+)/)||[])[1]`);\n    if (!token) {\n        throw new AuthRequiredError(WEIXIN_DOMAIN, 'Please log in to the WeChat Official Account platform and retry.');\n    }\n    await page.goto(`https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit_v2&action=edit&isNew=1&type=77&token=${token}&lang=zh_CN`);\n    await page.wait(4);\n    const hasTitle = await evaluate(page, '!!document.querySelector(\"textarea#title\")');\n    if (hasTitle !== true) {\n        throw new CommandExecutionError('WeChat article editor did not load. The session may have expired.');\n    }\n}\n\nasync function fillField(page, selector, value) {\n    return evaluate(page, `(() => {\n        var el = document.querySelector(${JSON.stringify(selector)});\n        if (!el) return { ok: false, reason: 'field not found' };\n        el.focus();\n        var proto = el.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;\n        var setter = Object.getOwnPropertyDescriptor(proto, 'value');\n        if (setter && setter.set) setter.set.call(el, ${JSON.stringify(value)});\n        else el.value = ${JSON.stringify(value)};\n        el.dispatchEvent(new InputEvent('input', { bubbles: true, data: ${JSON.stringify(value)} }));\n        el.dispatchEvent(new Event('change', { bubbles: true }));\n        el.blur();\n        return { ok: true };\n    })()`);\n}","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weixin/create-draft.js#L47-L83","documentation":"Thrown by navigateToEditor in clis/weixin/create-draft.js when, after navigating to the WeChat Official Account (mp.weixin.qq.com) article editor URL with a session token, the page does not contain the expected title textarea (textarea#title). The library interprets the missing editor UI as an expired or invalid login session, since the editor page only renders for authenticated sessions with a valid token.","triggerScenarios":"The MP session cookie expired (they expire after hours to days), the token query parameter is stale/invalid, the account lacks article-editing permissions, WeChat served a verification/login redirect instead of the editor, or the page rendered slowly so the 4-second wait was insufficient.","commonSituations":"Long-running automation sessions where the login was established hours/days earlier; multiple concurrent logins invalidating the WeChat session; WeChat forcing re-scan QR login; network slowness causing the editor DOM to not finish rendering within page.wait(4).","solutions":["Re-authenticate with the WeChat Official Account platform (re-scan the QR login) and refresh the stored session, then retry the command.","Retry the command once after a short delay in case the editor was slow to render.","Verify the account is a valid Official Account with permission to create drafts and that no captcha/verification wall intercepted navigation.","Increase the wait time or poll for textarea#title instead of relying on the fixed 4-second wait before running this command."],"exampleFix":"// before\nconst hasTitle = await evaluate(page, '!!document.querySelector(\"textarea#title\")');\nif (hasTitle !== true) {\n    throw new CommandExecutionError('WeChat article editor did not load. The session may have expired.');\n}\n// after\nlet hasTitle = false;\nfor (let i = 0; i < 5; i++) {\n    hasTitle = await evaluate(page, '!!document.querySelector(\"textarea#title\")');\n    if (hasTitle === true) break;\n    await page.wait(2);\n}\nif (hasTitle !== true) {\n    await relogin(WEIXIN_DOMAIN); // refresh expired session\n    throw new AuthRequiredError(WEIXIN_DOMAIN, 'Please log in to the WeChat Official Account platform and retry.');\n}","handlingStrategy":"retry","validationCode":"const loggedIn = await evaluate(page, '!!document.querySelector(\"textarea#title\") || !!document.querySelector(\".weui-desktop__title\")');\nif (!loggedIn) throw new AuthRequiredError('weixin', 'Session missing — re-login before running create-draft.');","typeGuard":"function isEditorLoaded(res) { return res === true; }","tryCatchPattern":"try {\n    await createDraftCommand(opts);\n} catch (e) {\n    if (/session may have expired/i.test(e.message)) {\n        await reloginWeixin();\n        return createDraftCommand(opts); // single retry after refresh\n    }\n    throw e;\n}","preventionTips":["Re-authenticate the WeChat session on a schedule (sessions expire in hours to a couple of days).","Health-check the session by loading the MP home page before running long drafts.","Avoid multiple concurrent sessions on the same account.","Poll for the editor DOM instead of trusting a fixed wait when networks are slow."],"tags":["wechat","session-expired","authentication","scraping"],"backgroundTag":"session-expired","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}