{"record":{"id":"60d42251e28f949c","repo":"jackwener/OpenCLI","slug":"forbidden","errorCode":"FORBIDDEN","errorMessage":"Gitee user page \"${username}\" is not accessible","messagePattern":"Gitee user page \"(.+?)\" is not accessible","errorType":"error_code","errorClass":"CliError","httpStatus":403,"severity":"error","filePath":"clis/gitee/user.js","lineNumber":171,"sourceCode":"          publicRepos,\n          giteeIndex,\n        };\n      })()\n    `);\n        const domSnapshotRecord = asRecord(rawDomSnapshot);\n        const domSnapshot = {\n            notFound: domSnapshotRecord?.notFound === true,\n            blocked: domSnapshotRecord?.blocked === true,\n            nickname: firstText(domSnapshotRecord?.nickname),\n            followers: normalizeCount(domSnapshotRecord?.followers),\n            publicRepos: normalizeCount(domSnapshotRecord?.publicRepos),\n            giteeIndex: normalizeCount(domSnapshotRecord?.giteeIndex),\n        };\n        if (domSnapshot.notFound) {\n            throw new CliError('NOT_FOUND', `Gitee user \"${username}\" does not exist`, 'Check the username and retry: opencli gitee user <username>');\n        }\n        if (domSnapshot.blocked) {\n            throw new CliError('FORBIDDEN', `Gitee user page \"${username}\" is not accessible`, 'The profile may be private/restricted, or the account may be unavailable');\n        }\n        const apiUrl = `${GITEE_USER_API}/${encodeURIComponent(username)}`;\n        const apiResponse = await fetch(apiUrl, {\n            headers: {\n                Accept: 'application/json',\n                'User-Agent': 'Mozilla/5.0',\n                Referer: profileUrl,\n            },\n        });\n        if (apiResponse.status === 404) {\n            throw new CliError('NOT_FOUND', `Gitee user \"${username}\" does not exist`, 'Check the username and retry: opencli gitee user <username>');\n        }\n        if (!apiResponse.ok) {\n            throw new CliError('REQUEST_FAILED', `Failed to read Gitee user profile API: ${apiResponse.status}`, 'Try again later or verify network access to gitee.com');\n        }\n        const apiUser = asRecord(await apiResponse.json());\n        const nickname = pickFirst(domSnapshot.nickname, firstText(apiUser?.name), firstText(apiUser?.login), username);\n        const followers = pickFirst(domSnapshot.followers, normalizeCount(apiUser?.followers), '-');","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gitee/user.js#L153-L189","documentation":"CliError with code FORBIDDEN thrown when the profile DOM snapshot reports blocked — the Gitee user page exists but its content is not accessible: private/restricted profile, suspended account, or an anti-bot/login wall served in place of the profile. The library raises FORBIDDEN with a hint that the profile may be private/restricted or the account unavailable.","triggerScenarios":"After page.goto(profileUrl), the snapshot's blocked flag is true — Gitee returned a verification/captcha page, a login-required wall, or an access-restricted profile instead of the public profile content.","commonSituations":"Gitee risk-control challenging the automated browser (captcha/slider) due to request rate or datacenter IP; viewing a private or suspended account; region-blocked content; session cookies flagged and access denied.","solutions":["Complete login via `opencli gitee auth` so the browser carries an authenticated session and retry","Slow down request rate / use a residential IP to avoid Gitee risk-control challenges","Verify in a normal browser whether the profile is private or the account suspended — if so, access is genuinely denied","Catch code FORBIDDEN and treat as non-retryable in batch scripts"],"exampleFix":"// before\nopencli gitee user someprivateuser   # FORBIDDEN: page not accessible\n// after\nopencli gitee auth                    # establish logged-in session\nopencli gitee user someprivateuser    # retry with auth cookies","handlingStrategy":"try-catch","validationCode":"// Check whether the profile page is publicly accessible before scraping\nconst res = await fetch(`https://gitee.com/${encodeURIComponent(username)}`);\nif (res.status === 403 || (await res.text()).includes('verify')) {\n  console.error(`Access to \"${username}\" profile is restricted or challenged`);\n  process.exit(1);\n}","typeGuard":"function isForbiddenCode(e) {\n  return e instanceof Error && e.code === 'FORBIDDEN';\n}","tryCatchPattern":"try {\n  profile = await giteeUser(username);\n} catch (e) {\n  if (e.code === 'FORBIDDEN') {\n    console.error(`Profile \"${username}\" is private/restricted or blocked — authenticate and retry`);\n    process.exit(e.exitCode ?? 1);\n  }\n  throw e;\n}","preventionTips":["Establish a logged-in session (`opencli gitee auth`) before scraping profiles","Throttle requests and use residential IPs to avoid risk-control challenges","Treat FORBIDDEN as non-retryable for genuinely private accounts","Detect captcha/verification pages early and surface a clear message"],"tags":["forbidden","access-denied","gitee","anti-bot"],"backgroundTag":"access-forbidden-403","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}