koala73/worldmonitor · error · ConvexError

COMPANY_MONITORING_CLAIM_POLICY_MIGRATION_REQUIRED

Error message

COMPANY_MONITORING_CLAIM_POLICY_MIGRATION_REQUIRED

What it means

Thrown by requireProviderClaimPolicy when a provider source is rollout-enabled (COMPANY_MONITORING_ROLLOUT_FLAGS) but the account row does not have the current company-monitoring claim policy (hasCurrentCompanyMonitoringClaimPolicy returns false). This forces accounts to be migrated to the current claim-policy schema before provider work runs for them.

Source

Thrown at convex/companyMonitoring/orchestration.ts:235

    exa: COMPANY_MONITORING_ROLLOUT_FLAGS.exaProvider,
    x: COMPANY_MONITORING_ROLLOUT_FLAGS.xProvider,
  };
  return flags[source];
}

function enabledSources(): Source[] {
  return (["exa", "x"] as const).filter(providerRolloutEnabled);
}

function requireProviderClaimPolicy(
  account: Doc<"companyMonitoringAccounts">,
  source: Source,
): void {
  if (
    providerRolloutEnabled(source) &&
    !hasCurrentCompanyMonitoringClaimPolicy(account)
  ) {
    throw new ConvexError("COMPANY_MONITORING_CLAIM_POLICY_MIGRATION_REQUIRED");
  }
}

async function updateAccountDueFromWork(ctx: MutationCtx, ownerAccountId: string) {
  const account = await ctx.db
    .query("companyMonitoringAccounts")
    .withIndex("by_logicalAccountId", (q) => q.eq("logicalAccountId", ownerAccountId))
    .unique();
  if (!account) return;
  const nextForSource = async (source: Source) => {
    const [due, leased] = await Promise.all([
      ctx.db
        .query("companyMonitoringScanWorkItems")
        .withIndex("by_account_source_state_selectionDueAt", (q) =>
          q.eq("ownerAccountId", ownerAccountId).eq("source", source).eq("state", "due"),
        )
        .first(),
      ctx.db

View on GitHub (pinned to ffec79ac33)

Solutions

  1. Run the account claim-policy migration/backfill so hasCurrentCompanyMonitoringClaimPolicy returns true for the affected account.
  2. If the rollout is premature, disable the provider flag in COMPANY_MONITORING_ROLLOUT_FLAGS until migration finishes.
  3. Confirm the account row writes the current policy version on creation and on policy upgrades.

Example fix

// before — account predates policy v2, work scheduling fails

// after — backfill account to current policy
await ctx.db.patch(account._id, {
  claimPolicyVersion: CURRENT_CLAIM_POLICY_VERSION,
  claimPolicyAppliedAt: Date.now(),
});
Defensive patterns

Strategy: validation

Validate before calling

if (providerRolloutEnabled(source) && !hasCurrentCompanyMonitoringClaimPolicy(account)) {
  throw new Error("account requires claim-policy migration before scheduling");
}

Type guard

function accountReadyForProvider(account: unknown, source: string): boolean {
  return !providerRolloutEnabled(source) || hasCurrentCompanyMonitoringClaimPolicy(account);
}

Prevention

When it happens

Trigger: Scheduling or claiming work for a rollout-enabled provider (exa/x) on an account whose claim policy is missing or out of date.

Common situations: A new claim-policy version shipped and existing accounts were not backfilled; rollout flag flipped on before the migration completed for an account; account created before the policy field existed.

Related errors


AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12). Data as JSON: /api/errors/44c18a5edf5037a2. Report an issue: GitHub.