twentyhq/twenty · error · Error

createCompany did not return an id

Error message

createCompany did not return an id

What it means

findOrCreateCompanyId in the partner application-intake service guards the createCompany mutation result. After dedup-by-name and domain extraction, it calls createCompany and asserts createCompany.id. An undefined id means the server returned a null/id-less company payload rather than throwing.

Source

Thrown at packages/twenty-apps/internal/twenty-partners/src/modules/partner/application-intake/services/find-or-create-company.service.ts:58

      );
      if (match !== undefined) {
        return match.node.id;
      }
      const pageInfo = existing.companies?.pageInfo;
      cursor = pageInfo?.hasNextPage ? (pageInfo.endCursor ?? null) : null;
    } while (cursor !== null);
  }

  const companyData: CoreSchema.CompanyCreateInput = {
    name: input.companyName.trim(),
  };
  if (domain !== undefined) {
    companyData.domainName = { primaryLinkUrl: domain };
  }
  const companyResult = await createCompany(client, companyData);
  const companyId = companyResult.createCompany?.id;
  if (companyId === undefined) {
    throw new Error('createCompany did not return an id');
  }
  return companyId;
}

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Inspect the raw createCompany response for null payload or errors array.
  2. Validate input.companyName.trim() is non-empty before calling findOrCreateCompanyId.
  3. Confirm the caller's role has Company create permission and Company is synced in metadata.
  4. Reproduce createCompany in the GraphQL playground to read the server rejection.

Example fix

// before
const companyResult = await createCompany(client, companyData);
const companyId = companyResult.createCompany?.id;
if (companyId === undefined) {
  throw new Error('createCompany did not return an id');
}

// after — guard the input and surface the result
if (!input.companyName.trim()) {
  throw new Error('companyName is required');
}
const companyResult = await createCompany(client, companyData);
const companyId = companyResult.createCompany?.id;
if (companyId === undefined) {
  throw new Error(`createCompany did not return an id (result=${JSON.stringify(companyResult)})`);
}
Defensive patterns

Strategy: type-guard

Validate before calling

import { isNonEmptyString } from 'twenty-shared';

if (!isNonEmptyString(input.companyName)) {
  throw new Error('companyName is required');
}
// before findOrCreateCompanyId

Type guard

const hasCreatedCompanyId = (r: unknown): r is { createCompany: { id: string } } =>
  typeof r === 'object' && r !== null &&
  typeof (r as any).createCompany?.id === 'string';

if (!hasCreatedCompanyId(companyResult)) {
  throw new Error(`createCompany returned no id: ${JSON.stringify(companyResult)}`);
}

Prevention

When it happens

Trigger: createCompany returns { createCompany: null } or no id. Causes: caller lacks Company create permission; companyName empty after trim; server-side validation; Company metadata out of sync; concurrent submission creating the same company leaving a race the dedup didn't catch.

Common situations: Partner application submitted with a whitespace-only companyName; role lacks Company create; manifest changed Company fields and metadata wasn't re-synced; duplicate application for an existing company created between the dedup lookup and the create.

Related errors


AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12). Data as JSON: /api/errors/88083e81e8da6bc1. Report an issue: GitHub.