jackwener/OpenCLI · error · ArgumentError

douyin user-videos requires a sec_uid

Error message

douyin user-videos requires a sec_uid

What it means

An ArgumentError thrown by normalizeSecUid when the sec_uid input is empty (after trimming / nullish coercion). Douyin user-videos requires a sec_uid to build the https://www.douyin.com/user/<sec_uid> page URL, and an empty value would produce a meaningless request. The error message carries a hint explaining the expected shape.

Source

Thrown at clis/douyin/user-videos.js:18

import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CliError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
import { fetchDouyinComments, fetchDouyinUserVideos } from './_shared/public-api.js';
export const MAX_USER_VIDEOS_LIMIT = 20;
export const USER_VIDEO_COMMENT_CONCURRENCY = 4;
export const DEFAULT_COMMENT_LIMIT = 10;
// sec_uid is base64url. Anything else (a nickname, a numeric UID, a search term)
// still resolves to a Douyin page, so without this guard the scrape silently
// returns some other account's videos.
// Current Douyin sec_uid values use the stable `MS4wLjABAAAA` prefix followed
// by a long base64url payload. Requiring the prefix prevents ordinary ASCII
// nicknames and long numeric UIDs from passing a shape-only character check.
const SEC_UID_PATTERN = /^MS4wLjABAAAA[A-Za-z0-9_-]{8,}$/;
const SEC_UID_HINT = 'sec_uid looks like MS4wLjABAAAA… — it is the last path segment of https://www.douyin.com/user/<sec_uid>, not a nickname or a numeric UID.';
export function normalizeSecUid(input) {
    const raw = String(input ?? '').trim();
    if (!raw)
        throw new ArgumentError('douyin user-videos requires a sec_uid', SEC_UID_HINT);
    const fromUrl = raw.match(/douyin\.com\/user\/([A-Za-z0-9_-]+)/);
    const candidate = fromUrl ? fromUrl[1] : raw;
    if (!SEC_UID_PATTERN.test(candidate))
        throw new ArgumentError(`"${raw}" is not a Douyin sec_uid`, SEC_UID_HINT);
    return candidate;
}
export function normalizeUserVideosLimit(limit) {
    const numeric = Number(limit);
    if (!Number.isFinite(numeric))
        return MAX_USER_VIDEOS_LIMIT;
    return Math.min(MAX_USER_VIDEOS_LIMIT, Math.max(1, Math.round(numeric)));
}
export function normalizeCommentLimit(limit) {
    const numeric = Number(limit);
    if (!Number.isFinite(numeric))
        return DEFAULT_COMMENT_LIMIT;
    return Math.min(DEFAULT_COMMENT_LIMIT, Math.max(1, Math.round(numeric)));
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Provide the sec_uid, e.g. `douyin user-videos --sec-uid MS4wLjABAAAA...`.
  2. Paste the last path segment of the creator's profile URL https://www.douyin.com/user/<sec_uid>.
  3. In scripts, check the variable is non-empty before invoking the command.

Example fix

// before
await run(['douyin', 'user-videos', '--sec-uid', process.env.DY_SEC_UID]);
// after
if (!process.env.DY_SEC_UID) throw new Error('DY_SEC_UID is not set');
await run(['douyin', 'user-videos', '--sec-uid', process.env.DY_SEC_UID]);
Defensive patterns

Strategy: validation

Validate before calling

const secUid = (input ?? '').trim();
if (!secUid) throw new Error('sec_uid is required: last path segment of https://www.douyin.com/user/<sec_uid>');

Type guard

function hasSecUid(v) {
  return typeof v === 'string' && v.trim().length > 0;
}

Try / catch

try {
  await run('douyin user-videos', { sec_uid });
} catch (e) {
  if (e.name === 'ArgumentError' && /requires a sec_uid/.test(e.message)) {
    console.error('Set --sec-uid from the profile URL');
    process.exitCode = 2;
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `douyin user-videos` (or secUid resolution path) with an empty --sec-uid flag, undefined/undefined-config value, or a value that is only whitespace.

Common situations: Config/env variable for the sec_uid not set; a shell variable expanding to empty; passing a profile URL that failed to parse earlier and yielded an empty string downstream.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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