jackwener/OpenCLI · error · CommandExecutionError

WeChat article editor did not load. The session may have exp

Error message

WeChat article editor did not load. The session may have expired.

What it means

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.

Source

Thrown at clis/weixin/create-draft.js:65

    const mimeType = IMAGE_MIME_TYPES.get(extension);
    if (!mimeType) {
        throw new ArgumentError('weixin create-draft cover-image must be JPEG, PNG, GIF, or WebP');
    }
    return { absPath, fileName: path.basename(absPath), mimeType };
}

async function navigateToEditor(page) {
    await page.goto(WEIXIN_HOME);
    await page.wait(3);
    const token = await evaluate(page, `(window.location.href.match(/token=(\\d+)/)||[])[1]`);
    if (!token) {
        throw new AuthRequiredError(WEIXIN_DOMAIN, 'Please log in to the WeChat Official Account platform and retry.');
    }
    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`);
    await page.wait(4);
    const hasTitle = await evaluate(page, '!!document.querySelector("textarea#title")');
    if (hasTitle !== true) {
        throw new CommandExecutionError('WeChat article editor did not load. The session may have expired.');
    }
}

async function fillField(page, selector, value) {
    return evaluate(page, `(() => {
        var el = document.querySelector(${JSON.stringify(selector)});
        if (!el) return { ok: false, reason: 'field not found' };
        el.focus();
        var proto = el.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
        var setter = Object.getOwnPropertyDescriptor(proto, 'value');
        if (setter && setter.set) setter.set.call(el, ${JSON.stringify(value)});
        else el.value = ${JSON.stringify(value)};
        el.dispatchEvent(new InputEvent('input', { bubbles: true, data: ${JSON.stringify(value)} }));
        el.dispatchEvent(new Event('change', { bubbles: true }));
        el.blur();
        return { ok: true };
    })()`);
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-authenticate with the WeChat Official Account platform (re-scan the QR login) and refresh the stored session, then retry the command.
  2. Retry the command once after a short delay in case the editor was slow to render.
  3. Verify the account is a valid Official Account with permission to create drafts and that no captcha/verification wall intercepted navigation.
  4. Increase the wait time or poll for textarea#title instead of relying on the fixed 4-second wait before running this command.

Example fix

// before
const hasTitle = await evaluate(page, '!!document.querySelector("textarea#title")');
if (hasTitle !== true) {
    throw new CommandExecutionError('WeChat article editor did not load. The session may have expired.');
}
// after
let hasTitle = false;
for (let i = 0; i < 5; i++) {
    hasTitle = await evaluate(page, '!!document.querySelector("textarea#title")');
    if (hasTitle === true) break;
    await page.wait(2);
}
if (hasTitle !== true) {
    await relogin(WEIXIN_DOMAIN); // refresh expired session
    throw new AuthRequiredError(WEIXIN_DOMAIN, 'Please log in to the WeChat Official Account platform and retry.');
}
Defensive patterns

Strategy: retry

Validate before calling

const loggedIn = await evaluate(page, '!!document.querySelector("textarea#title") || !!document.querySelector(".weui-desktop__title")');
if (!loggedIn) throw new AuthRequiredError('weixin', 'Session missing — re-login before running create-draft.');

Type guard

function isEditorLoaded(res) { return res === true; }

Try / catch

try {
    await createDraftCommand(opts);
} catch (e) {
    if (/session may have expired/i.test(e.message)) {
        await reloginWeixin();
        return createDraftCommand(opts); // single retry after refresh
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


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