twentyhq/twenty · error · PdlOperationError

OPERATION_FAILED

OPERATION_FAILED

Error message

Failed to create workflow "${seed.workflowName}": no id returned.

What it means

While seeding the PDL enrichment workflow, the code calls `createWorkflow` with a name and expects an `id`. If `createResult.createWorkflow?.id` is undefined it throws a `PdlOperationError` (`OPERATION_FAILED`). This runs during app install/setup seeding, so the error indicates the workflow could not be created in this workspace.

Source

Thrown at packages/twenty-apps/public/people-data-labs/src/logic-functions/utils/seed-enrichment-workflow.ts:46

    return {
      objectNameSingular: seed.objectNameSingular,
      workflowName: seed.workflowName,
      status: 'skipped',
      workflowId: existingWorkflowId,
    };
  }

  const createResult = (await client.mutation({
    createWorkflow: {
      __args: { data: { name: seed.workflowName } },
      id: true,
    },
  })) as { createWorkflow?: { id?: string } };

  const workflowId = createResult.createWorkflow?.id;

  if (!isDefined(workflowId)) {
    throw new PdlOperationError(
      `Failed to create workflow "${seed.workflowName}": no id returned.`,
    );
  }

  const versionsResult = (await client.query({
    workflowVersions: {
      __args: { filter: { workflowId: { eq: workflowId } } },
      edges: { node: { id: true, status: true } },
    },
  })) as {
    workflowVersions?: { edges?: { node?: { id?: string; status?: string } }[] };
  };

  const draftVersionId = versionsResult.workflowVersions?.edges?.find(
    (edge) => edge.node?.status === 'DRAFT',
  )?.node?.id;

  if (!isDefined(draftVersionId)) {

View on GitHub (pinned to 1f5dd2bbd2)

Solutions

  1. Check whether a workflow named `seed.workflowName` already exists in the workspace; if so, reuse it instead of creating (or make the seed idempotent).
  2. Log the full `createResult` including any `errors` to see the server's reason for omitting the id.
  3. Confirm the acting user/role has permission to create workflows.
  4. Validate `seed.workflowName` against the workflow name constraints (uniqueness, length, character set).

Example fix

// before
const workflowId = createResult.createWorkflow?.id;
if (!isDefined(workflowId)) {
  throw new PdlOperationError(`Failed to create workflow "${seed.workflowName}": no id returned.`);
}

// after — make the seed idempotent and surface server errors
let workflowId = createResult.createWorkflow?.id;
if (!isDefined(workflowId)) {
  const existing = await findWorkflowByName(client, seed.workflowName);
  workflowId = existing?.id;
}
if (!isDefined(workflowId)) {
  throw new PdlOperationError(
    `Failed to create workflow "${seed.workflowName}": no id returned (errors=${JSON.stringify((createResult as any).errors ?? [])})`,
  );
}
Defensive patterns

Strategy: validation

Validate before calling

// Make the seed idempotent: look up an existing workflow by name first.
const existing = await findWorkflowByName(client, seed.workflowName);
if (existing?.id) return existing.id;

Type guard

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

Prevention

When it happens

Trigger: The `createWorkflow` mutation returns no id because the workflow name violates a constraint (duplicate name, invalid characters, length), the acting user cannot create workflows, or the server returned an error shape that leaves `id` unset. The `seed.workflowName` is interpolated so the offending name is visible.

Common situations: Re-running the seeder against a workspace where the workflow already exists with the same name and the server rejects duplicates by returning no id; a permissions change on the installing user; a workflow-schema change requiring fields the seed does not set.

Related errors


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