{"record":{"id":"1ec295375b9be66c","repo":"jackwener/OpenCLI","slug":"weibo-delete-url-must-be-a-weibo-com-or-weibo-cn","errorCode":null,"errorMessage":"weibo delete: URL must be a weibo.com or weibo.cn post URL","messagePattern":"weibo delete: URL must be a weibo\\.com or weibo\\.cn post URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/weibo/delete.js","lineNumber":24,"sourceCode":"import { requireObjectEvaluateResult, unwrapEvaluateResult } from './utils.js';\n\nconst WEIBO_HOST_RE = /(^|\\.)weibo\\.(com|cn)$/i;\nconst POST_ID_RE = /^[A-Za-z0-9]{4,32}$/;\n\nfunction normalizePostId(raw) {\n    const input = String(raw ?? '').trim();\n    if (!input) {\n        throw new ArgumentError('weibo delete: id cannot be empty');\n    }\n\n    let candidate = input;\n    try {\n        const url = new URL(input);\n        if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n            throw new ArgumentError('weibo delete: URL must use http or https');\n        }\n        if (!WEIBO_HOST_RE.test(url.hostname)) {\n            throw new ArgumentError('weibo delete: URL must be a weibo.com or weibo.cn post URL');\n        }\n        const parts = url.pathname.split('/').filter(Boolean);\n        if (url.hostname.toLowerCase().endsWith('weibo.cn') && parts[0] === 'status') {\n            candidate = parts[1] ?? '';\n        } else {\n            candidate = parts.at(-1) ?? '';\n        }\n    } catch (error) {\n        if (error instanceof ArgumentError) throw error;\n    }\n\n    candidate = String(candidate ?? '').trim();\n    if (!POST_ID_RE.test(candidate)) {\n        throw new ArgumentError('weibo delete: id must be a numeric idstr, mblogid, or Weibo post URL');\n    }\n    return candidate;\n}\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weibo/delete.js#L6-L42","documentation":"When the id argument looks like a URL, its hostname must match WEIBO_HOST_RE, i.e. end with weibo.com or weibo.cn. URLs from other domains are rejected with ArgumentError so the command never deletes based on ids scraped from unrelated sites.","triggerScenarios":"Passing a shortener link (t.cn, bit.ly), a mirror/aggregator URL, or a m.weibo.cn-adjacent domain not covered by the regex, or pasting the wrong link entirely (e.g. a Twitter/X URL).","commonSituations":"Users copying share links from third-party Weibo clients or shorteners, or confusing the post's t.cn short link (used in tweets) with the canonical weibo.com URL.","solutions":["Open the short link in a browser and copy the final weibo.com/weibo.cn URL it redirects to","Use the id directly from `weibo me`/`weibo post` output instead of a URL","Ensure the domain is exactly weibo.com or weibo.cn (subdomains like www are fine; other brands are not)"],"exampleFix":"// before\nweibo delete --id 'https://t.cn/A6bCdEf'\n// after\nweibo delete --id 'https://weibo.com/1234567890/AbCdEfGhI'","handlingStrategy":"validation","validationCode":"function isWeiboPostUrl(u) {\n  try { const url = new URL(u); return /(^|\\.)weibo\\.(com|cn)$/i.test(url.hostname); }\n  catch { return false; }\n}","typeGuard":"function isWeiboHost(hostname) {\n  return /(^|\\.)weibo\\.(com|cn)$/i.test(hostname);\n}","tryCatchPattern":"try {\n  await cliDelete({ id: input });\n} catch (err) {\n  if (err instanceof ArgumentError && /weibo\\.com or weibo\\.cn post URL/.test(err.message)) {\n    throw new Error('Resolve short links (t.cn) to the final weibo.com URL first');\n  } else throw err;\n}","preventionTips":["Resolve t.cn and other shorteners in a browser before passing the final URL","Use the id from `weibo me`/`weibo post` output to sidestep URL handling entirely","Double-check you copied a weibo.com/weibo.cn link, not another site's","Validate hostnames in scripts before invoking the CLI"],"tags":["weibo","argument-validation","url-validation"],"backgroundTag":"invalid-url-host","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}