jackwener/OpenCLI · error · ArgumentError

bilibili follow target must be a valid space.bilibili.com/<u

Error message

bilibili follow target must be a valid space.bilibili.com/<uid> URL

What it means

When the target looks like a space.bilibili.com URL, resolveTargetMid parses the mid out of it via parseSpaceMidUrl; if the parse fails it throws this ArgumentError instead of falling through to user search, because a malformed profile URL should never hit the search endpoint.

Source

Thrown at clis/bilibili/follow.js:28

import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
import { parseSpaceMidUrl, fetchRelationAttribute, waitForRelation } from './relation.js';
import { apiPost, getSelfUid, requireOkPayload, resolveUid } from './utils.js';

/**
 * Pull a uid out of a `space.bilibili.com/<uid>` URL before falling back to the
 * generic resolver. `resolveUid` only handles bare digits or usernames; without
 * this short-circuit a profile URL would get sent to the user-search endpoint
 * and likely return nothing.
 */
async function resolveTargetMid(page, raw) {
    const trimmed = String(raw ?? '').trim();
    if (!trimmed) {
        throw new ArgumentError('bilibili follow target cannot be empty');
    }
    if (/^(?:https?:\/\/)?space\.bilibili\.com\//i.test(trimmed)) {
        const mid = parseSpaceMidUrl(trimmed);
        if (!mid) {
            throw new ArgumentError('bilibili follow target must be a valid space.bilibili.com/<uid> URL');
        }
        return mid;
    }
    try {
        return await resolveUid(page, trimmed);
    } catch (error) {
        if (error instanceof EmptyResultError) throw error;
        throw new ArgumentError(
            `Cannot resolve Bilibili target from input: ${trimmed}`,
            error instanceof Error ? error.message : String(error),
        );
    }
}

cli({
    site: 'bilibili',
    name: 'follow',
    access: 'write',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the canonical numeric URL form: https://space.bilibili.com/123456789.
  2. If you only have a username, pass the username directly instead of a URL so it goes through resolveUid.
  3. Extract the numeric uid manually and pass it as the target.

Example fix

// before
bilibili follow --target 'https://space.bilibili.com/dynamic'
// after
bilibili follow --target 'https://space.bilibili.com/9469745'
Defensive patterns

Strategy: validation

Validate before calling

if (/^(?:https?:\/\/)?space\.bilibili\.com\//i.test(target) && !/^\d+$/.test(new URL(target.startsWith('http') ? target : 'https://' + target).pathname.split('/')[1] ?? '')) {
  throw new Error('space URL must contain a numeric uid');
}

Type guard

function isSpaceUidUrl(s) {
  const m = /^(?:https?:\/\/)?space\.bilibili\.com\/(\d+)\/?$/i.exec(s.trim());
  return m !== null;
}

Try / catch

try {
  const mid = await resolveTargetMid(page, raw);
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('space.bilibili.com')) {
    console.error(`'${raw}' is not a valid space URL; pass a numeric uid instead`);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a string starting with space.bilibili.com/ that contains no numeric mid, e.g. 'space.bilibili.com/', 'https://space.bilibili.com/abc', or a URL with extra path segments the parser cannot handle.

Common situations: Copy-pasting a truncated profile URL, using a personalized space URL (custom domain or /name path), or editing a URL and deleting the numeric id.

Related errors


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