{"record":{"id":"e65bc1e3415b0d8e","repo":"vercel-labs/agent-skills","slug":"project-scope-mismatch","errorCode":"PROJECT_SCOPE_MISMATCH","errorMessage":"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.","messagePattern":"PROJECT_SCOPE_MISMATCH: (.+?) 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\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skills/vercel-optimize/scripts/collect-signals.mjs","lineNumber":137,"sourceCode":"  }\n\n  if (!frameworkSupport.ok && continueUnsupportedFramework) {\n    log('continuing after unsupported framework blocker because --continue-unsupported-framework was set');\n  }\n\n  log('resolving Vercel CLI command scope…');\n  const commandScope = await resolveCommandScope(project);\n  if (!commandScope.ok) {\n    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>\\`.`);\n  }\n  const scope = commandScope.cliScope || undefined;\n  log(`command scope resolved (source=${commandScope.source}; scoped=${scope ? 'yes' : 'no'})`);\n\n  log('validating linked project belongs to the resolved scope…');\n  const projectCfg = await getProjectConfig(project.projectId, project.orgId);\n  const projectScope = validateProjectScope(projectCfg, project);\n  if (!projectScope.ok) {\n    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.`);\n  }\n  log(`project scope verified (source=${projectScope.source})`);\n\n  log('checking Observability Plus configuration…');\n  const observabilityPlusConfig = await checkObservabilityPlusConfiguration({\n    orgId: project.orgId,\n    projectId: project.projectId,\n  });\n  log(`observabilityPlusPreflight=${observabilityPlusConfig.access === true ? 'enabled' : observabilityPlusConfig.blocker ?? 'unknown'} (${observabilityPlusConfig.source})`);\n\n  let oplus = observabilityPlusConfig.access === true;\n  if (observabilityPlusConfig.access == null) {\n    log('Observability Plus configuration preflight inconclusive; falling back to metrics schema probe…');\n    oplus = await hasObservabilityPlus(scope);\n  }\n  log(`observabilityPlus=${oplus}`);\n\n  const schema = oplus ? await getMetricsSchema(scope) : null;","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/vercel-labs/agent-skills/blob/b8caa260a420a73042e35521de4b5c8baf6446cc/skills/vercel-optimize/scripts/collect-signals.mjs#L119-L155","documentation":"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.","triggerScenarios":"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.","commonSituations":"Mismatched env vars copied from different projects; a project transferred between teams after linking; developer belongs to several teams and picked the wrong orgId.","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."],"exampleFix":"# before — projectId from team A, orgId from team B\n$ VERCEL_PROJECT_ID=prj_A VERCEL_ORG_ID=team_B node scripts/collect-signals.mjs\n-> PROJECT_SCOPE_MISMATCH\n\n# after — both from the same scope\n$ VERCEL_PROJECT_ID=prj_A VERCEL_ORG_ID=team_A node scripts/collect-signals.mjs","handlingStrategy":"validation","validationCode":"const projectCfg = await getProjectConfig(project.projectId, project.orgId);\nconst projectScope = validateProjectScope(projectCfg, project);\nif (!projectScope.ok) {\n  throw new Error(`projectId/orgId point at different scopes: ${projectScope.detail}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const projectScope = validateProjectScope(await getProjectConfig(project.projectId, project.orgId), project);\n  if (!projectScope.ok) throw new Error(`PROJECT_SCOPE_MISMATCH: ${projectScope.detail}`);\n} catch (err) {\n  if (err.message.startsWith('PROJECT_SCOPE_MISMATCH')) {\n    // ask user to confirm project + team, re-link, then retry\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["scope","config","consistency","vercel"],"backgroundTag":null,"analyzedSha":"b8caa260a420a73042e35521de4b5c8baf6446cc","analyzedAt":"2026-08-13T06:03:29.508Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}