jackwener/OpenCLI · error · ArgumentError

tid must be a numeric thread id

Error message

tid must be a numeric thread id

What it means

ArgumentError thrown by the 1point3acres thread command when the `tid` argument is missing, empty, or not a pure decimal number. Thread ids in the site URLs (thread-<tid>-<page>-1.html) must be numeric, so the CLI validates strictly before building the request instead of producing a malformed URL.

Source

Thrown at clis/1point3acres/thread.js:35

cli({
    site: '1point3acres',
    name: 'thread',
    access: 'read',
    description: '一亩三分地 帖子详情 + 楼层(主楼 + 回复)',
    domain: 'www.1point3acres.com',
    strategy: Strategy.PUBLIC,
    browser: false,
    args: [
        { name: 'tid', required: true, positional: true, help: '帖子 ID(数字,见 `hot`/`latest` 返回的 tid)' },
        { name: 'page', type: 'int', default: 1, help: '楼层分页页码(默认 1)' },
        { name: 'limit', type: 'int', default: 10, help: '返回楼层条数(默认 10,含主楼)' },
        { name: 'contentLimit', type: 'int', default: 400, help: '每楼正文截断长度(默认 400 字符,最少 50)' },
    ],
    columns: ['floor', 'pid', 'author', 'postTime', 'content', 'url'],
    func: async (args) => {
        const tid = String(args.tid || '').trim();
        if (!/^\d+$/.test(tid)) {
            throw new ArgumentError('tid must be a numeric thread id');
        }
        const page = normalizePositiveInteger(args.page, 1, 'page');
        const limit = normalizePositiveInteger(args.limit, 10, 'limit');
        const contentLimit = normalizePositiveInteger(args.contentLimit, 400, 'contentLimit', { min: 50 });

        const url = `${BASE}/thread-${tid}-${page}-1.html`;
        const html = await fetchHtml(url);

        // Sanity: real thread page will contain postlist + at least one post div.
        if (!/id="postlist"/.test(html) && !/id="post_\d+"/.test(html)) {
            throw new EmptyResultError('1point3acres thread', `帖子 ${tid} 不存在或被删除`);
        }

        // Split posts: each post block is bounded by <div id="post_<PID>">…</div> next post or postlist end.
        // NOTE: intermediate objects intentionally use postId/body/offset (not pid/html/start) to
        // avoid being mistaken for row-shaped objects by the silent-column-drop audit.
        const postBlocks = [];
        const re = /<div id="post_(\d+)"[^>]*>/g;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass the numeric thread id, e.g. tid: '2856313'
  2. Extract the tid from a thread URL: thread-2856313-1-1.html → tid 2856313
  3. Trim the input and ensure it matches /^\d+$/ before calling
  4. Do not pass a URL, slug, or decimal number as tid

Example fix

// before
thread({ tid: 'https://www.1point3acres.com/bbs/thread-2856313-1-1.html' })
// after
const tid = url.match(/thread-(\d+)-/)?.[1];
thread({ tid });
Defensive patterns

Strategy: validation

Validate before calling

function isValidTid(tid) { return /^\d+$/.test(String(tid ?? '').trim()); }
if (!isValidTid(input)) { /* prompt/fix before calling */ }

Type guard

const isTid = (v) => typeof v === 'string' || typeof v === 'number';
const asTid = (v) => {
  const s = String(v ?? '').trim();
  return /^\d+$/.test(s) ? s : null;
};

Try / catch

try {
  await thread({ tid });
} catch (e) {
  if (e instanceof ArgumentError && /tid/.test(e.message)) {
    console.error('Provide the numeric thread id, e.g. thread-2856313-1-1.html → 2856313');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the thread command with tid omitted, an empty string, whitespace, a thread slug/URL pasted instead of the id, or a non-numeric value like 'abc' or '123.4'.

Common situations: Pasting a full thread URL instead of the numeric tid; passing tid as a number with decimal or a string with units; forgetting the required argument in a script; shell quoting mangling the value.

Related errors


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