jackwener/OpenCLI · error · CommandExecutionError

Bilibili user ${mid} is blocked; unblock first before follow

Error message

Bilibili user ${mid} is blocked; unblock first before following.

What it means

fetchRelationAttribute returns the relation attribute byte; 128 means the target has blocked you, and attribute 2/6 would mean already following. Because Bilibili rejects follow requests toward users who blocked you, the command fails fast with this explicit CommandExecutionError telling you to unblock first (you cannot unblock someone else's block — it means the relationship is blocked from your side's block list context per this message).

Source

Thrown at clis/bilibili/follow.js:74

        },
    ],
    columns: ['mid', 'name', 'status', 'url'],
    func: async (page, kwargs) => {
        if (!page) {
            throw new CommandExecutionError('Browser session required for bilibili follow');
        }
        const mid = await resolveTargetMid(page, kwargs.target);
        const self = await getSelfUid(page);
        if (mid === self) {
            throw new ArgumentError('Cannot follow yourself');
        }
        const attribute = await fetchRelationAttribute(page, mid);
        const url = `https://space.bilibili.com/${mid}`;
        if (attribute === 2 || attribute === 6) {
            return [{ mid, name: '', status: 'already-following', url }];
        }
        if (attribute === 128) {
            throw new CommandExecutionError(
                `Bilibili user ${mid} is blocked; unblock first before following.`,
            );
        }
        // act=1 follow, act=2 unfollow. re_src=11 is the community-standard
        // "web" source value used by third-party libs (bilibili-api-python etc.);
        // omitting it makes the modify API reject with a vague code.
        const payload = await apiPost(page, '/x/relation/modify', {
            params: { fid: mid, act: 1, re_src: 11 },
        });
        requireOkPayload(payload, 'relation modify');
        await waitForRelation(page, mid, (nextAttribute) => nextAttribute === 2 || nextAttribute === 6, 'following');
        return [{ mid, name: '', status: 'followed', url }];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Remove the block via bilibili.com (or the block API) for that user, then retry the follow.
  2. Skip this user in batch jobs — the follow cannot succeed while the block exists.
  3. Check the attribute first with a relation query before attempting follow in automation.

Example fix

// before
await follow(mid);
// after
const attr = await fetchRelationAttribute(page, mid);
if (attr === 128) throw new Error(`skip ${mid}: blocked`);
await follow(mid);
Defensive patterns

Strategy: try-catch

Validate before calling

const attr = await fetchRelationAttribute(page, mid);
if (attr === 128) throw new Error(`${mid} is blocked; cannot follow until unblocked`);
if (attr === 2 || attr === 6) console.log(`${mid} already followed`);

Type guard

function isBlockableRelation(attr) {
  return typeof attr === 'number' && attr !== 2 && attr !== 6 && attr !== 128;
}

Try / catch

try {
  await follow(mid);
} catch (e) {
  if (String(e.message).includes('is blocked')) {
    console.warn(`skipping ${mid}: blocked relationship`);
    return; // do not retry until unblocked
  }
  throw e;
}

Prevention

When it happens

Trigger: Running bilibili follow against a mid whose relation attribute is exactly 128 (blocked state).

Common situations: Attempting to re-follow a user you previously blocked, following someone after a dispute, batch scripts carrying stale target lists.

Related errors


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