{"record":{"id":"ddb5426694f25751","repo":"langfuse/langfuse","slug":"name-conflict","errorCode":"name_conflict","errorMessage":"An evaluation rule named \"${params.input.name}\" already exists in this project. Use PATCH /api/public/unstable/evaluation-rules/${existing.id} to update it instead of creating a duplicate.","messagePattern":"An evaluation rule named \"(.+?)\" already exists in this project\\. Use PATCH /api/public/unstable/evaluation-rules/(.+?) to update it instead of creating a duplicate\\.","errorType":"http","errorClass":null,"httpStatus":409,"severity":"error","filePath":"web/src/features/evals/server/unstable-public-api/evaluation-rule-service.ts","lineNumber":324,"sourceCode":"  input: PostUnstableEvaluationRuleBodyType;\n  evaluatorId?: string;\n  auditScope?: Pick<ApiAccessScope, \"orgId\" | \"apiKeyId\">;\n}) {\n  // Scoped to the targets this API can write. Rule names carry no uniqueness constraint, so this\n  // only exists to hand back the id to PATCH instead of a second rule -- and PATCH 404s on the\n  // trace/dataset rules the backfill brought in, so including those would be a dead end.\n  const existing = await prisma.evaluationRule.findFirst({\n    where: {\n      projectId: params.projectId,\n      name: params.input.name,\n      targetObject: {\n        in: [EvalTargetObject.EVENT, EvalTargetObject.EXPERIMENT],\n      },\n    },\n    select: { id: true },\n  });\n  if (existing) {\n    throw createStructuredPublicApiError({\n      httpCode: 409,\n      code: \"name_conflict\",\n      message: `An evaluation rule named \"${params.input.name}\" already exists in this project. Use PATCH /api/public/unstable/evaluation-rules/${existing.id} to update it instead of creating a duplicate.`,\n      details: { field: \"name\" },\n    });\n  }\n  if (params.input.enabled) {\n    await assertActivePublicApiEvaluationRuleLimitNotExceeded(params.projectId);\n  }\n  await assertEvaluationRuleFilterValuesExistForProject({\n    projectId: params.projectId,\n    target: params.input.target,\n    filters: params.input.filter,\n  });\n\n  const requestedAssignments = getRequestedEvaluatorAssignments(params.input);\n  const evaluators = await Promise.all(\n    requestedAssignments.map(({ evaluator }, index) =>","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/langfuse/langfuse/blob/59d92c7cf365150d10b753b5a0d1708902a2ed60/web/src/features/evals/server/unstable-public-api/evaluation-rule-service.ts#L306-L342","documentation":"409 name_conflict when creating an evaluation rule whose name already exists for an event/experiment target rule in the project. The message points to the PATCH endpoint of the existing rule.","triggerScenarios":"POST /api/public/unstable/evaluation-rules with a name that matches an existing EVENT/EXPERIMENT-target rule in the same project.","commonSituations":"Re-running setup scripts that create rules idempotently-by-name; migrating configs between environments.","solutions":["Use PATCH /api/public/unstable/evaluation-rules/{id} with the id from the error message instead of POST","Pick a unique rule name","Delete the existing rule first if it is obsolete"],"exampleFix":"// before\nPOST /api/public/unstable/evaluation-rules { name: \"daily-eval\", ... }\n// after\nPATCH /api/public/unstable/evaluation-rules/<existing.id> { ... }","handlingStrategy":"validation","validationCode":"const existing = await findRuleByName(name);\nif (existing) return patchRule(existing.id, body);\nawait createRule({ ...body, name });","typeGuard":null,"tryCatchPattern":"try { await createRule(body); } catch (e) { if (e?.error?.code === \"name_conflict\") { const id = e.error.message.match(/evaluation-rules\\/([\\w-]+)/)?.[1]; await patchRule(id, body); } else throw e; }","preventionTips":["Make create-by-name idempotent: look up before create","Derive rule names deterministically so duplicates are detectable"],"tags":["langfuse","evals","public-api","name-conflict"],"backgroundTag":"duplicate-resource-name","analyzedSha":"59d92c7cf365150d10b753b5a0d1708902a2ed60","analyzedAt":"2026-08-27T22:22:00.402Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}