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
- Check whether a workflow named `seed.workflowName` already exists in the workspace; if so, reuse it instead of creating (or make the seed idempotent).
- Log the full `createResult` including any `errors` to see the server's reason for omitting the id.
- Confirm the acting user/role has permission to create workflows.
- 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
- Make workflow seeding idempotent (lookup-or-create) so re-runs do not collide on name.
- Inspect the client `errors` array when the id is absent.
- Validate the workflow name against workspace constraints before creating.
- Confirm the acting user has workflow-create permission.
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
- OPERATION_FAILED
- CONFIGURATION
- createCompany did not return an id
- createPerson did not return an id
- createOpportunity did not return an id
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/2de97d4bd716ddb1.
Report an issue: GitHub.