{"record":{"id":"f9e7a2ed97696ae6","repo":"jackwener/OpenCLI","slug":"cannot-resolve-bilibili-target-from-input-trimm","errorCode":null,"errorMessage":"Cannot resolve Bilibili target from input: ${trimmed}","messagePattern":"Cannot resolve Bilibili target from input: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/follow.js","lineNumber":36,"sourceCode":" * and likely return nothing.\n */\nasync function resolveTargetMid(page, raw) {\n    const trimmed = String(raw ?? '').trim();\n    if (!trimmed) {\n        throw new ArgumentError('bilibili follow target cannot be empty');\n    }\n    if (/^(?:https?:\\/\\/)?space\\.bilibili\\.com\\//i.test(trimmed)) {\n        const mid = parseSpaceMidUrl(trimmed);\n        if (!mid) {\n            throw new ArgumentError('bilibili follow target must be a valid space.bilibili.com/<uid> URL');\n        }\n        return mid;\n    }\n    try {\n        return await resolveUid(page, trimmed);\n    } catch (error) {\n        if (error instanceof EmptyResultError) throw error;\n        throw new ArgumentError(\n            `Cannot resolve Bilibili target from input: ${trimmed}`,\n            error instanceof Error ? error.message : String(error),\n        );\n    }\n}\n\ncli({\n    site: 'bilibili',\n    name: 'follow',\n    access: 'write',\n    description: '关注 B站用户（官方 API，需登录）',\n    domain: 'www.bilibili.com',\n    strategy: Strategy.COOKIE,\n    args: [\n        {\n            name: 'target',\n            required: true,\n            positional: true,","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/follow.js#L18-L54","documentation":"Fallback path: when the target is neither empty nor a space URL, resolveTargetMid tries resolveUid (username/keyword search). If that fails for any reason other than EmptyResultError, the original error is wrapped in this ArgumentError with the raw input echoed, so callers see which input failed and why.","triggerScenarios":"Passing a username/nickname that no longer exists, a renamed account, input with invisible characters, or resolveUid failing due to risk control / search API errors.","commonSituations":"User changed their Bilibili nickname, targeting a deactivated account, or search endpoint throttled (-412) making the lookup fail.","solutions":["Use the numeric UID directly — it is stable and skips search entirely.","Re-check the username on bilibili.com; copy it again without surrounding whitespace.","If resolveUid failed due to throttling, wait and retry; the cause is in the wrapped second argument."],"exampleFix":"// before\nbilibili follow --target '旧昵称'\n// after\nbilibili follow --target 9469745","handlingStrategy":"fallback","validationCode":"if (!/^\\d+$/.test(target) && /^(?:https?:\\/\\/)?space\\.bilibili\\.com\\//i.test(target) === false) {\n  console.warn(`target '${target}' will go through user search; prefer a numeric uid`);\n}","typeGuard":"function isNumericUid(s) {\n  return /^\\d+$/.test(String(s).trim());\n}","tryCatchPattern":"try {\n  return await resolveTargetMid(page, raw);\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.startsWith('Cannot resolve Bilibili target')) {\n    console.error(`Could not resolve '${raw}': ${e.cause ?? ''}. Try the numeric uid.`);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Use numeric UIDs — they never require search resolution","Re-copy usernames after account renames","Strip whitespace/zero-width characters from input","Wrap resolveUid failures with the cause so logs show the real reason"],"tags":["argument-error","resolution","bilibili"],"backgroundTag":"entity-resolution-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}