koala73/worldmonitor · error · ConvexError
COMPANY_MONITORING_ACCESS_DENIED
Error message
COMPANY_MONITORING_ACCESS_DENIED
What it means
Thrown by requireActiveAccount (_shared.ts:98-101) when activeAccountForOwner returns null — meaning no active, entitled, non-terminal companyMonitoringAccounts row exists for the given ownerUserId. A ConvexError with this exact message surfaces to the client as a 4xx-style application error. This guards every Company Monitoring entry point that requires a live entitled account.
Source
Thrown at convex/companyMonitoring/_shared.ts:100
entitlement.planKey !== "free" &&
entitlement.features.tier > 0 &&
entitlement.validUntil >= Date.now(),
);
if (
!account ||
!activeEntitlement ||
account.lifecycle !== "entitled" ||
account.ownerUserId !== ownerUserId ||
account.terminalReason
) {
return null;
}
return account;
}
export async function requireActiveAccount(ctx: CompanyMonitoringCtx, ownerUserId: string) {
const account = await activeAccountForOwner(ctx, ownerUserId);
if (!account) throw new ConvexError("COMPANY_MONITORING_ACCESS_DENIED");
return account;
}
type CustomerClaimType =
| "alias"
| "domain"
| "legal_identifier"
| "x_account_id"
| "x_handle"
| "location"
| "customer_reference";
export function customerClaimAllowedUses(type: CustomerClaimType) {
if (
type === "alias" ||
type === "domain" ||
type === "legal_identifier" ||
type === "x_account_id" ||View on GitHub (pinned to ffec79ac33)
Solutions
- Gate the client-side UI on the user's entitlement status before allowing the action — do not call Company Monitoring endpoints for free/lapsed users.
- If the user should be entitled, verify their entitlements row exists and validUntil >= now via `npx convex run` or the dashboard.
- If the account was never provisioned, trigger syncCompanyMonitoringAccountFromEntitlement (via an entitlement write or a provisioned entry point like requireProvisionedAccount).
- If the account was terminalized in error, investigate the terminalReason and lifecycleSequence in the companyMonitoringAccounts row.
Defensive patterns
Strategy: validation
Validate before calling
// Before calling a Company Monitoring endpoint, check entitlement client-side:
const entitled = entitlement && entitlement.planKey !== "free" && entitlement.features.tier > 0 && entitlement.validUntil >= Date.now();
if (!entitled) {
// show upgrade/paywall UI instead of calling the backend
} Try / catch
try {
await ctx.runMutation(internal.companyMonitoring.someEndpoint, args);
} catch (err) {
if (err instanceof ConvexError && err.message === "COMPANY_MONITORING_ACCESS_DENIED") {
// surface a paywall/upgrade prompt to the user
throw new Error("Company Monitoring requires an active PRO subscription.");
}
throw err;
} Prevention
- Gate Company Monitoring UI on the user's entitlement status before allowing actions.
- Handle COMPANY_MONITORING_ACCESS_DENIED as a business-level 403 (show paywall), not a crash.
- Ensure the account is provisioned via an entitlement write before the user first interacts with the feature.
When it happens
Trigger: Calling a Company Monitoring mutation/query for a user who has no entitlement (free plan), whose entitlement expired (validUntil < now), whose account lifecycle is not 'entitled', whose account has a terminalReason set, or whose account ownerUserId does not match. Also when the account simply does not exist yet (never provisioned).
Common situations: A free-plan user attempts to use Company Monitoring features. A user's PRO subscription lapsed and the account transitioned to 'entitlement_lapsed'. The user's account was terminalized (owner_deleted/account_deleted). The account was never provisioned because the entitlement write path hasn't synced yet.
Related errors
- COMPANY_MONITORING_ACCESS_DENIED
- COMPANY_MONITORING_ACCESS_DENIED
- COMPANY_MONITORING_ACCOUNT_INACTIVE
- COMPANY_MONITORING_ACCOUNT_INACTIVE
- PRO_REQUIRED
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/dc5ea24de7e94353.
Report an issue: GitHub.