jackwener/OpenCLI · error · CommandExecutionError

Xianyu publish form was not detected

Error message

Xianyu publish form was not detected

What it means

After the auth check, the flow verifies the publish form is present via buildExtractPageStateEvaluate(); if initState.hasPublishForm is falsy it throws CommandExecutionError('Xianyu publish form was not detected'). The page loaded and you are logged in, but the expected form elements were not found in the DOM.

Source

Thrown at clis/xianyu/publish.js:399

        { name: 'category', required: true, positional: true, help: '商品分类关键词(如:手机、衣服、图书)' },
        { name: 'original_price', type: 'float', help: '原价(选填,用于显示折扣)' },
        { name: 'location', help: '所在地区(选填,如:杭州)' },
        { name: 'images', help: '本地图片路径,多张用逗号分隔(选填,如:/tmp/a.jpg,/tmp/b.jpg)' },
    ],
    columns: ['status', 'item_id', 'title', 'price', 'condition', 'url', 'message'],
    func: async (page, kwargs) => {
        const data = normalizePublishArgs(kwargs);
        // 1. 导航到发布页
        await page.goto(buildPublishUrl());
        await page.wait(3);

        // 2. 检查登录状态
        const initState = await page.evaluate(buildExtractPageStateEvaluate());
        if (initState?.requiresAuth) {
            throw new AuthRequiredError('www.goofish.com', '发布闲鱼需要先登录,请在 Chrome 中打开 goofish.com 并完成登录');
        }
        if (!initState?.hasPublishForm) {
            throw new CommandExecutionError('Xianyu publish form was not detected', 'Confirm goofish.com is logged in and the publish page finished loading.');
        }

        // 3. 选择分类(先于其他字段,因为分类可能影响表单结构)
        const categoryResult = await page.evaluate(buildSelectCategoryEvaluate(data.category));
        if (!categoryResult?.ok) {
            throw new CommandExecutionError(`Xianyu category selection failed: ${categoryResult?.reason || 'unknown-reason'}`);
        }
        await page.wait(1.5);

        // 4. 填充表单
        const fillResult = await page.evaluate(buildFillFormEvaluate(data));
        if (!fillResult?.ok) {
            const missing = Array.isArray(fillResult?.missing) ? fillResult.missing.join(', ') : 'unknown';
            throw new CommandExecutionError(`Xianyu publish form fill failed; missing fields: ${missing}`);
        }
        await page.wait(1);

        // 5. 上传图片(如果有)

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Increase the wait before evaluating page state (the flow waits page.wait(3) — raise it on slow networks)
  2. Manually open the publish URL in the same Chrome profile to confirm the form renders
  3. Update the library if goofish changed its DOM (selectors in buildExtractPageStateEvaluate are stale)
  4. Complete any anti-bot/verification interstitial in the browser first

Example fix

// before
await page.goto(buildPublishUrl());
await page.wait(3);
// after
await page.goto(buildPublishUrl());
await page.wait(8); // allow SPA to finish rendering on slow networks
Defensive patterns

Strategy: retry

Validate before calling

const state = await page.evaluate(buildExtractPageStateEvaluate());
if (!state?.hasPublishForm) {
  throw new Error('Publish form not rendered yet; increase wait or check the URL');
}

Type guard

function hasPublishForm(state) {
  return Boolean(state && state.hasPublishForm === true);
}

Try / catch

try {
  await publish(data);
} catch (e) {
  if (e instanceof CommandExecutionError && /publish form was not detected/.test(e.message)) {
    await sleep(3000);
    await publish(data);
  } else throw e;
}

Prevention

When it happens

Trigger: page.goto(buildPublishUrl()) lands on a page where buildExtractPageStateEvaluate returns no hasPublishForm: redirect off the publish route, page still loading when state is extracted, redesigned DOM, or a bot-check/interstitial page.

Common situations: Slow networks where the SPA hasn't rendered form fields when evaluate runs, goofish frontend redesign, region/language redirects, or anti-bot verification pages.

Related errors


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