Documentslangfuse/langfuse
Evaluator Configuration and Status Management
Evaluator Configuration and Status Management
Type
Topic
Status
Published
Created
Jul 8, 2026
Updated
Jul 8, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Evaluator Configuration and Status Management#

Langfuse evaluators (LLM-as-a-Judge jobs) have two distinct status mechanisms:

  1. Blocking — automatic pausing when LLM/model configuration is missing or broken
  2. Deactivation — manual ACTIVE/INACTIVE toggle with server-side guards that prevent certain changes once an evaluator has run on existing traces

Config Blocking#

Evaluators are automatically blocked when the worker detects a configuration problem during execution. The isJobConfigExecutable function gates all eval runs — a config must have status === ACTIVE and blockedAt === null to be executable. If blocked, the job execution is cancelled immediately.

Blocking is triggered from four sources :

EvaluatorBlockSourceWhen
INVALID_MODEL_CONFIGModel config invalid during eval execution
LLM_COMPLETION_ERRORAuth failure (401) or model unavailable (404) from LLM call
LLM_API_KEY_DELETIONAn LLM connection used by the evaluator is deleted
DEFAULT_EVAL_MODEL_DELETIONThe project's default evaluation model is deleted

Block Reasons & Messages#

Block reason, short label, and user-facing message are defined in evalConfigBlocking.ts:

EvaluatorBlockReasonShort Label
LLM_CONNECTION_AUTH_INVALIDAuthentication failed
LLM_CONNECTION_MISSINGLLM connection missing
DEFAULT_EVAL_MODEL_MISSINGDefault evaluation model missing
EVAL_MODEL_CONFIG_INVALIDEvaluation model invalid
EVAL_MODEL_UNAVAILABLEModel unavailable
PROVIDER_ACCOUNT_NOT_READYProvider account setup incomplete

Database Fields#

Three nullable columns on JobConfiguration track blocked state :

  • blockedAt — timestamp when the block was set
  • blockReasonEvaluatorBlockReason enum value
  • blockMessage — human-readable remediation text

Notifications & Side Effects#

When blockEvaluatorConfigs is called, it:

  1. Updates the DB record with blockedAt, blockReason, and blockMessage
  2. Sends an email to project admins via notifyBlockedEvaluatorConfigs
  3. Invalidates project eval config caches so workers stop picking up the config immediately

Frontend: Blocked State UI#

The EvaluatorPausedCallout component renders a yellow alert banner when evalConfig.blockedAt is set. It surfaces:

  • The blockMetadata.shortLabel and elapsed time since blocked
  • The full blockMessage from getEvaluatorBlockMetadata
  • A context-aware "fix it" link via getEvaluatorBlockResolutionPath: LLM auth/missing issues resolve to /settings/llm-connections; other issues link to the evaluator template or general evals page
  • A Reactivate button (calls updateEvalJob with status: ACTIVE), with onSuccess and onError toast notifications

Reactivation & Block Field Reset#

When updateEvalJob receives a status update, the router automatically clears block fields by merging resetEvalConfigBlockFields into the update payload . Before activating a previously-blocked config, the router calls validateEvalTemplateCanRun to confirm the underlying issue is resolved .


Server-Side Guards on updateEvalJob#

Beyond blocking, updateEvalJob enforces two immutability rules for evaluators that have already run on existing traces :

  1. timeScope immutability — Once EXISTING is in timeScope, it cannot be removed. Throws BAD_REQUEST: "The evaluator ran on existing traces already. This cannot be changed anymore."

  2. EXISTING-only deactivation guard — For legacy TRACE/DATASET targets (not EVENT), if timeScope is ["EXISTING"] only, the evaluator cannot be set to INACTIVE. Throws BAD_REQUEST: "The evaluator is running on existing traces only and cannot be deactivated."

The DeactivateEvalConfig switch pre-disables itself when timeScope === ["EXISTING"] , preventing the second guard from being triggered via the toggle UI.


Frontend Error Handling: Silent Failure & Fix#

Bug (issue #13315): DeactivateEvalConfig had no onError handler on the updateEvalJob mutation. When the server rejected a request (e.g., EXISTING-scope guard), the error was silently swallowed — the form reverted with no toast or inline message .

Fix (PR #14064): Added showErrorToast in the onError callback, consistent with the pattern in evaluator-paused-callout.tsx and inner-evaluator-form.tsx .

Known residual issue: The onClick handler still calls mutateAsync without await or .catch() , leaving a dangling unhandled promise rejection on failure. The recommended fix is switching to mutate (fire-and-forget), as evaluator-paused-callout.tsx does .


Key Files#

FilePurpose
packages/shared/src/features/evals/evalConfigBlocking.tsBlock reason enum, metadata, resolution paths, isJobConfigExecutable
packages/shared/src/server/services/blockEvaluatorConfigs.tsService: write block fields, notify admins, invalidate caches
web/src/features/evals/server/router.tsupdateEvalJob mutation with server-side guards (lines 1084–1200+)
web/src/features/evals/components/evaluator-paused-callout.tsxUI alert for blocked evaluators with reactivation button
web/src/features/evals/components/deactivate-config.tsxActive/Inactive toggle switch
worker/src/features/evaluation/evalService.tsTriggers blocking on LLM errors during eval execution