{"record":{"id":"182c8ab77ef513a3","repo":"jackwener/OpenCLI","slug":"bilibili-unfollow-target-must-be-a-valid-space-bil","errorCode":null,"errorMessage":"bilibili unfollow target must be a valid space.bilibili.com/<uid> URL","messagePattern":"bilibili unfollow target must be a valid space\\.bilibili\\.com/<uid> URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/unfollow.js","lineNumber":20,"sourceCode":" * Bilibili unfollow — removes a follow relation via the official write API.\n * Mirror of follow.js with act=2. If the viewer is not currently following the\n * target, the API call is skipped and `not-following` is returned without\n * touching state.\n */\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\nimport { parseSpaceMidUrl, fetchRelationAttribute, waitForRelation } from './relation.js';\nimport { apiPost, getSelfUid, requireOkPayload, resolveUid } from './utils.js';\n\nasync function resolveTargetMid(page, raw) {\n    const trimmed = String(raw ?? '').trim();\n    if (!trimmed) {\n        throw new ArgumentError('bilibili unfollow 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 unfollow 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: 'unfollow',\n    access: 'write',","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/unfollow.js#L2-L38","documentation":"resolveTargetMid in clis/bilibili/unfollow.js throws this ArgumentError when the unfollow target looks like a space.bilibili.com URL (matched by the prefix regex) but parseSpaceMidUrl fails to extract a numeric uid from it. The library intentionally does not fall back to UID/name resolution once the input appears to be a space URL, because treating a malformed URL as a username would silently unfollow the wrong account. It is a fail-fast input validation error.","triggerScenarios":"Calling `bilibili unfollow --target <url>` (or invoking mid/resolveTargetMid programmatically) where the target matches /^(?:https?:\\/\\/)?space\\.bilibili\\.com\\//i but the remainder is not a valid numeric uid, e.g. 'space.bilibili.com/', 'space.bilibili.com/abc', 'https://space.bilibili.com' with no path.","commonSituations":"Copy-pasting a truncated space URL from the browser address bar; hand-typing the URL and forgetting the uid; a script interpolating an empty or non-numeric variable into the URL; pasting a profile link from the bilibili app that uses a different path format.","solutions":["Ensure the target is a complete URL of the form https://space.bilibili.com/<numeric-uid>, e.g. space.bilibili.com/1234567","If you have the numeric uid directly, pass the plain uid string (or username) instead of a URL so it goes through the resolveUid path","Trim whitespace and remove any trailing path fragments (e.g. /dynamic) beyond the uid","Verify the target variable in your script is not empty or partially interpolated before calling the command"],"exampleFix":"// before\nawait bilibiliUnfollow({ target: 'https://space.bilibili.com/' });\n// after\nawait bilibiliUnfollow({ target: 'https://space.bilibili.com/1234567' });","handlingStrategy":"validation","validationCode":"function isValidSpaceUrl(t) {\n  return /^https?:\\/\\/space\\.bilibili\\.com\\/\\d+\\/?$/i.test(String(t ?? '').trim());\n}\nif (!isValidSpaceUrl(target) && !/^\\d+$/.test(String(target ?? '').trim())) {\n  throw new Error(`Target must be a numeric uid or full space.bilibili.com/<uid> URL, got: ${target}`);\n}","typeGuard":"function isSpaceUrlWithUid(v) {\n  if (typeof v !== 'string') return false;\n  const m = v.trim().match(/^(?:https?:\\/\\/)?space\\.bilibili\\.com\\/(\\d+)\\/?$/i);\n  return m !== null;\n}","tryCatchPattern":"try {\n  await bilibiliUnfollow({ target });\n} catch (err) {\n  if (err instanceof ArgumentError && /valid space\\.bilibili\\.com/.test(err.message)) {\n    console.error(`Bad target URL: ${target}. Use https://space.bilibili.com/<uid>`);\n  } else throw err;\n}","preventionTips":["Copy the full profile URL including the numeric uid from the browser address bar","Prefer passing the bare numeric uid when you have it","Add a regex pre-check for space.bilibili.com/\\d+ in scripts before invoking the command"],"tags":["argument-validation","bilibili","cli-input"],"backgroundTag":"invalid-url-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}