{"record":{"id":"380edaa1256f18bb","repo":"langfuse/langfuse","slug":"org-id-and-org-id-csv-are-mutually-exclusive","errorCode":null,"errorMessage":"--org-id and --org-id-csv are mutually exclusive","messagePattern":"--org-id and --org-id-csv are mutually exclusive","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/src/ee/features/sfdc-sync/scripts/backfillSfdcLeads.ts","lineNumber":186,"sourceCode":"      \"batch-size\": { type: \"string\", default: \"500\" },\n      limit: { type: \"string\" },\n      \"exclude-org\": { type: \"string\", multiple: true, default: [] },\n      \"exclude-org-csv\": { type: \"string\" },\n      \"skip-recent-minutes\": { type: \"string\", default: \"0\" },\n    },\n    allowPositionals: false,\n  });\n\n  const toInt = (v: string | undefined, fallback: number) => {\n    if (v === undefined) return fallback;\n    const n = Number.parseInt(v, 10);\n    if (!Number.isFinite(n) || n < 0)\n      throw new Error(`Invalid numeric flag value: ${v}`);\n    return n;\n  };\n\n  if (values[\"org-id\"] && values[\"org-id-csv\"])\n    throw new Error(\"--org-id and --org-id-csv are mutually exclusive\");\n  if (values[\"org-id\"] && values[\"start-after\"])\n    throw new Error(\"--start-after makes no sense with a single --org-id\");\n\n  // Refuse to run without the demo-org exclusion: on Cloud every user holds\n  // a VIEWER membership in the demo org (created at signup, never synced by\n  // the live sync), so an unexcluded demo org would bridge every user to one\n  // Account and flip every organic signup's lead source to \"Invite\".\n  if (!env.NEXT_PUBLIC_DEMO_ORG_ID)\n    throw new Error(\n      \"NEXT_PUBLIC_DEMO_ORG_ID is not set — refusing to run. Set it to the \" +\n        \"region's demo org id (same value as the region's web deployment) so \" +\n        \"the demo org is excluded from sync, lead sources, and the orphan sweep.\",\n    );\n  const excludeOrgIds = new Set<string>(values[\"exclude-org\"] as string[]);\n  excludeOrgIds.add(env.NEXT_PUBLIC_DEMO_ORG_ID);\n\n  const alreadyDoneOrgIds = new Set<string>(\n    values[\"exclude-org-csv\"]","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/langfuse/langfuse/blob/59d92c7cf365150d10b753b5a0d1708902a2ed60/web/src/ee/features/sfdc-sync/scripts/backfillSfdcLeads.ts#L168-L204","documentation":"parseCli rejects running the backfill with both --org-id (single org) and --org-id-csv (bulk list) because they define conflicting iteration modes. The script iterates either one org or a CSV of orgs, never both.","triggerScenarios":"Invoking backfillSfdcLeads.ts with both --org-id=<id> and --org-id-csv=<path> on the same command line.","commonSituations":"Copy-pasting a bulk command and adding --org-id for a quick test, or iterating on flags and forgetting to remove one of the two.","solutions":["Keep only one mode: drop --org-id for a bulk run or drop --org-id-csv for a single-org run"],"exampleFix":"// before\n--org-id clx123 --org-id-csv orgs.csv\n// after\n--org-id-csv orgs.csv","handlingStrategy":"validation","validationCode":"const hasOrgId = argv.includes('--org-id');\nconst hasCsv = argv.includes('--org-id-csv');\nif (hasOrgId && hasCsv) {\n  console.error('Choose exactly one of --org-id or --org-id-csv');\nprocess.exit(2);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Template the two invocation modes as separate documented commands"],"tags":["cli","sfdc-sync","mutually-exclusive-flags"],"backgroundTag":"conflicting-cli-options","analyzedSha":"59d92c7cf365150d10b753b5a0d1708902a2ed60","analyzedAt":"2026-08-27T22:22:00.402Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}