koala73/worldmonitor · error · ConvexError
INVALID_COMPANY_PATCH
Error message
INVALID_COMPANY_PATCH
What it means
Thrown by updateCompanyForOwner when the patch's claim mutation arrays exceed COMPANY_MONITORING_LIMITS.maxClaimsPerCompany. The check runs on the raw addClaims and removeClaimIds lengths before any deduplication, so the limit applies to the request size, not the resulting claim set.
Source
Thrown at convex/companyMonitoring/companies.ts:211
handler: async (ctx, args) => {
const account = await requireActiveAccount(ctx, args.ownerUserId);
const company = await ctx.db
.query("companyMonitoringCompanies")
.withIndex("by_account_companyId", (q) =>
q.eq("ownerAccountId", account.logicalAccountId).eq("companyId", args.companyId),
)
.unique();
if (!company || company.lifecycle === "removed" || !company.name || !company.domicileCountry) {
throw new ConvexError("NOT_FOUND");
}
const patch = args.patch;
const addClaimInputs = patch.addClaims ?? [];
const removeClaimInputs = patch.removeClaimIds ?? [];
if (
addClaimInputs.length > COMPANY_MONITORING_LIMITS.maxClaimsPerCompany ||
removeClaimInputs.length > COMPANY_MONITORING_LIMITS.maxClaimsPerCompany
) {
throw new ConvexError("INVALID_COMPANY_PATCH");
}
const hasName = Object.prototype.hasOwnProperty.call(patch, "name");
const hasDomicile = Object.prototype.hasOwnProperty.call(patch, "domicileCountry");
const hasCustomerReference = Object.prototype.hasOwnProperty.call(patch, "customerReference");
const normalizedFields = normalizeMonitoredCompanyInput({
name: hasName ? patch.name! : company.name,
domicileCountry: hasDomicile ? patch.domicileCountry! : company.domicileCountry,
customerReference: hasCustomerReference
? patch.customerReference
: company.customerReference,
});
if (hasCustomerReference && normalizedFields.customerReference) {
const conflict = await findNoopByCustomerReference(
ctx,
account.logicalAccountId,
normalizedFields.customerReference,
);View on GitHub (pinned to ffec79ac33)
Solutions
- Split the claim additions/removals into batches each no larger than COMPANY_MONITORING_LIMITS.maxClaimsPerCompany.
- Read the limit from the shared company-monitoring-contract on the client and cap the patch size before sending.
- Prefer targeted single-claim edits over wholesale list replacement.
Example fix
// before
await update({ companyId, patch: { addClaims: allClaims, removeClaimIds: allRemovals } });
// after
const LIMIT = COMPANY_MONITORING_LIMITS.maxClaimsPerCompany;
for (let i = 0; i < allClaims.length; i += LIMIT) {
await update({ companyId, patch: { addClaims: allClaims.slice(i, i + LIMIT) } });
}
for (let i = 0; i < allRemovals.length; i += LIMIT) {
await update({ companyId, patch: { removeClaimIds: allRemovals.slice(i, i + LIMIT) } });
} Defensive patterns
Strategy: validation
Validate before calling
import { COMPANY_MONITORING_LIMITS } from "shared/company-monitoring-contract";
const LIMIT = COMPANY_MONITORING_LIMITS.maxClaimsPerCompany;
if ((patch.addClaims?.length ?? 0) > LIMIT || (patch.removeClaimIds?.length ?? 0) > LIMIT) {
throw new Error("Claim patch exceeds per-company limit");
} Type guard
function patchWithinClaimLimit(patch: { addClaims?: unknown[]; removeClaimIds?: unknown[] }, limit: number): boolean {
return (patch.addClaims?.length ?? 0) <= limit && (patch.removeClaimIds?.length ?? 0) <= limit;
} Prevention
- Paginate claim additions and removals in batches of maxClaimsPerCompany.
- Read the limit from the shared contract, never hard-code it.
When it happens
Trigger: Submitting a patch with addClaims.length > maxClaimsPerCompany or removeClaimIds.length > maxClaimsPerCompany in a single updateCompanyForOwner call.
Common situations: Bulk-import UI that sends the entire claim list in one patch; a migration script that batches too many claim edits per company; client not paginating claim removals.
Related errors
- COMPANY_MONITORING_EVIDENCE_SUBJECTS_INVALID
- COMPANY_MONITORING_EVIDENCE_BATCH_INVALID
- COMPANY_MONITORING_EVIDENCE_EXPANSION_INVALID
- INVALID_COMPANY_MONITORING_COHORT
- COUNTRIES_LIMIT_EXCEEDED
AI-assisted analysis of koala73/worldmonitor@ffec79ac33 (2026-08-12).
Data as JSON: /api/errors/5e8de0507b21711d.
Report an issue: GitHub.