langgenius/dify · warning · TracingConfigIsExist

trace_config_is_exist

trace_config_is_exist

Error message

Trace config is exist.

What it means

Raised as TracingConfigIsExist in POST /apps/{app_id}/ops-trace when OpsService.create_tracing_app_config returns a falsy result (api/controllers/console/app/ops_trace.py:116-117). The service returns falsy when a tracing config for the same app+provider already exists, so creation is refused to prevent duplicates. Note: the outer `except Exception as e: raise BadRequest(str(e))` ultimately surfaces this as a 400 with the message text.

Source

Thrown at api/controllers/console/app/ops_trace.py:117

    @console_ns.response(403, "Insufficient permissions")
    @setup_required
    @login_required
    @account_initialization_required
    @edit_permission_required
    @rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_TRACING_CONFIG)
    @get_app_model
    @model_validate(TraceConfigPayload)
    def post(self, req_data: TraceConfigPayload, app_model: App):
        """Create a new trace app configuration"""
        try:
            result = OpsService.create_tracing_app_config(
                app_id=app_model.id,
                tracing_provider=req_data.tracing_provider,
                tracing_config=req_data.tracing_config,
                session=db.session(),
            )
            if not result:
                raise TracingConfigIsExist()
            if result.get("error"):
                raise TracingConfigCheckError()
            return result
        except Exception as e:
            raise BadRequest(str(e))

    @console_ns.doc("update_trace_app_config")
    @console_ns.doc(description="Update an existing tracing configuration for an application")
    @console_ns.doc(params={"app_id": "Application ID"})
    @console_ns.expect(console_ns.models[TraceConfigPayload.__name__])
    @console_ns.response(
        200,
        "Tracing configuration updated successfully",
        console_ns.models[TraceAppConfigResponse.__name__],
    )
    @console_ns.response(400, "Invalid request parameters or configuration not found")
    @console_ns.response(403, "Insufficient permissions")
    @setup_required

View on GitHub (pinned to ef8544b173)

Solutions

  1. Use PATCH /apps/{app_id}/ops-trace to update the existing config instead of POSTing a new one.
  2. DELETE the existing trace config first if you genuinely want to recreate it.
  3. Guard the UI submit handler against double-submission (disable button on click).
  4. Query the current trace config before deciding whether to POST or PATCH.

Example fix

// before: always POST
fetch(`/apps/${appId}/ops-trace`, {method:'POST', body: ...})
// after: choose method by existence
const existing = await fetch(`/apps/${appId}/ops-trace?provider=${provider}`).then(r=>r.json())
await fetch(`/apps/${appId}/ops-trace`, {method: existing ? 'PATCH' : 'POST', body: ...})
Defensive patterns

Strategy: validation

Validate before calling

// Decide POST vs PATCH based on existing config
const existing = await fetch(`/apps/${appId}/ops-trace?provider=${provider}`).then(r=>r.ok?r.json():null)
const method = existing ? 'PATCH' : 'POST'
await fetch(`/apps/${appId}/ops-trace`, {method, body: JSON.stringify(payload)})

Try / catch

try {
  await createTraceConfig(appId, payload)
} catch (e) {
  if (e.code === 'trace_config_is_exist') return patchTraceConfig(appId, payload)
  throw e
}

Prevention

When it happens

Trigger: POSTing a trace config for an app+provider pair that already has a stored tracing config. The endpoint is idempotent-refusing — a second create for the same provider triggers it.

Common situations: Front-end re-submitting the create form after a successful save; integration test running twice without cleanup; user switching provider and re-creating instead of PATCHing; double-click on the save button.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/ce9f02df9e18c38a. Report an issue: GitHub.