vercel-labs/agent-skills · error · Error
PROJECT_SCOPE_MISMATCH
PROJECT_SCOPE_MISMATCH
Error message
PROJECT_SCOPE_MISMATCH: ${projectScope.detail} Ask the user to confirm the exact Vercel project and team/personal scope, then rerun after `vercel link --yes --project <project-name-or-id> --team <team-slug>` or after setting both VERCEL_PROJECT_ID and VERCEL_ORG_ID for the intended scope. What it means
Thrown by main() when validateProjectScope(getProjectConfig(...), project) returns {ok:false}. After resolving a CLI scope, the collector fetches the project config for (projectId, orgId) and checks that the project's actual owner matches the resolved scope. A mismatch means the linked projectId/orgId pair points at a project owned by a different account than the CLI is scoped to — querying would silently hit the wrong project, so it aborts.
Source
Thrown at skills/vercel-optimize/scripts/collect-signals.mjs:137
}
if (!frameworkSupport.ok && continueUnsupportedFramework) {
log('continuing after unsupported framework blocker because --continue-unsupported-framework was set');
}
log('resolving Vercel CLI command scope…');
const commandScope = await resolveCommandScope(project);
if (!commandScope.ok) {
throw new Error(`SCOPE_UNRESOLVED: ${commandScope.detail} Run \`vercel switch <team>\` or re-link with \`vercel link --yes --project <project-name-or-id> --team <team-slug>\`.`);
}
const scope = commandScope.cliScope || undefined;
log(`command scope resolved (source=${commandScope.source}; scoped=${scope ? 'yes' : 'no'})`);
log('validating linked project belongs to the resolved scope…');
const projectCfg = await getProjectConfig(project.projectId, project.orgId);
const projectScope = validateProjectScope(projectCfg, project);
if (!projectScope.ok) {
throw new Error(`PROJECT_SCOPE_MISMATCH: ${projectScope.detail} Ask the user to confirm the exact Vercel project and team/personal scope, then rerun after \`vercel link --yes --project <project-name-or-id> --team <team-slug>\` or after setting both VERCEL_PROJECT_ID and VERCEL_ORG_ID for the intended scope.`);
}
log(`project scope verified (source=${projectScope.source})`);
log('checking Observability Plus configuration…');
const observabilityPlusConfig = await checkObservabilityPlusConfiguration({
orgId: project.orgId,
projectId: project.projectId,
});
log(`observabilityPlusPreflight=${observabilityPlusConfig.access === true ? 'enabled' : observabilityPlusConfig.blocker ?? 'unknown'} (${observabilityPlusConfig.source})`);
let oplus = observabilityPlusConfig.access === true;
if (observabilityPlusConfig.access == null) {
log('Observability Plus configuration preflight inconclusive; falling back to metrics schema probe…');
oplus = await hasObservabilityPlus(scope);
}
log(`observabilityPlus=${oplus}`);
const schema = oplus ? await getMetricsSchema(scope) : null;View on GitHub (pinned to b8caa260a4)
Solutions
- Confirm the exact project id and its owning team/personal scope with the user, then re-link: `vercel link --yes --project <id> --team <team-slug>`.
- Set both VERCEL_PROJECT_ID and VERCEL_ORG_ID for the SAME scope and rerun.
- Inspect the project in the Vercel dashboard to read its real owner, and align the local link/env to that.
Example fix
# before — projectId from team A, orgId from team B $ VERCEL_PROJECT_ID=prj_A VERCEL_ORG_ID=team_B node scripts/collect-signals.mjs -> PROJECT_SCOPE_MISMATCH # after — both from the same scope $ VERCEL_PROJECT_ID=prj_A VERCEL_ORG_ID=team_A node scripts/collect-signals.mjs
Defensive patterns
Strategy: validation
Validate before calling
const projectCfg = await getProjectConfig(project.projectId, project.orgId);
const projectScope = validateProjectScope(projectCfg, project);
if (!projectScope.ok) {
throw new Error(`projectId/orgId point at different scopes: ${projectScope.detail}`);
} Try / catch
try {
const projectScope = validateProjectScope(await getProjectConfig(project.projectId, project.orgId), project);
if (!projectScope.ok) throw new Error(`PROJECT_SCOPE_MISMATCH: ${projectScope.detail}`);
} catch (err) {
if (err.message.startsWith('PROJECT_SCOPE_MISMATCH')) {
// ask user to confirm project + team, re-link, then retry
}
throw err;
} Prevention
- Source VERCEL_PROJECT_ID and VERCEL_ORG_ID from the same project/scope.
- Re-link after moving a project between teams.
- Cross-check the project owner in the Vercel dashboard before setting env vars.
When it happens
Trigger: VERCEL_PROJECT_ID and VERCEL_ORG_ID set for different accounts (id from team A, org from team B); a stale link where the project was moved to another team; whoami currentTeam resolved to a team that doesn't own the linked project.
Common situations: Mismatched env vars copied from different projects; a project transferred between teams after linking; developer belongs to several teams and picked the wrong orgId.
Related errors
AI-assisted analysis of vercel-labs/agent-skills@b8caa260a4 (2026-08-13).
Data as JSON: /api/errors/e65bc1e3415b0d8e.
Report an issue: GitHub.