deepseek-ai/deepseek-harness · error

conversation fallback Definition must declare a target

Error message

conversation fallback Definition must declare a target

What it means

registerFallback() installs the single Definition used when no ordinary Definition matches an event. The fallback is rendered through its own target/buildViewNode pair — there is no match dispatch to route it — so a fallback without a target is rejected. The preceding assertDefinitionTarget already requires target and buildViewNode to be declared together, so reaching this error means the Definition has neither: a match-style shape was passed where a render-target shape is required.

Source

Thrown at packages/client/runtime/src/client/conversation/event-registry.ts:37

  register(definition: ConversationNodeDefinition): () => void {
    assertDefinitionTarget(definition)
    return this.registerDefinition(
      definition.kind,
      definition,
      `conversation Definition "${definition.kind}" is already registered`,
      `conversationEvents.register(${JSON.stringify(definition.kind)})`,
    )
  }

  /**
   * Register the sole fallback used only when no ordinary Definition matches.
   * @param definition - fallback Definition.
   * @returns idempotent disposer.
   */
  registerFallback(definition: ConversationNodeDefinition): () => void {
    assertDefinitionTarget(definition)
    const target = definition.target
    if (target === undefined) throw new Error('conversation fallback Definition must declare a target')
    if (this.fallback !== undefined) throw new Error('conversation fallback Definition is already registered')
    const owner = this.ctx
    const dispose = owner.effect(() => {
      this.fallback = definition
      this.refresh()
      return () => {
        if (this.fallback !== definition) return
        this.fallback = undefined
        this.refresh()
      }
    }, `conversationEvents.registerFallback(${JSON.stringify(definition.kind)})`)
    return () => { void dispose() }
  }

  /**
   * Return the current unmatched-event fallback.
   * @returns installed fallback, when present.
   */

View on GitHub (pinned to b150a551b8)

Solutions

  1. Declare both target and buildViewNode on the fallback Definition — they must appear together.
  2. If the object was meant for match dispatch (match/update), register it with register() instead of registerFallback().
  3. Inspect the Definition construction site: a missing pair is usually a spread or partial-object bug, not an intentional shape.

Example fix

// before — match-style Definition passed as the fallback
events.registerFallback({ kind: 'generic', match, update }) // no target/buildViewNode → throws

// after — the fallback declares its render target pair
events.registerFallback({
  kind: 'generic',
  target: 'generic',
  buildViewNode: m => ({ key: m.id, kind: 'generic', id: m.id, target: 'generic', data: m }),
})
Defensive patterns

Strategy: type-guard

Type guard

import type { ConversationNodeDefinition } from '../contract/conversation.ts'
type FallbackDefinition = ConversationNodeDefinition & {
  target: string
  buildViewNode: NonNullable<ConversationNodeDefinition['buildViewNode']>
}
const isFallbackDefinition = (d: ConversationNodeDefinition): d is FallbackDefinition =>
  d.target !== undefined && d.buildViewNode !== undefined

Prevention

When it happens

Trigger: Calling conversationEvents.registerFallback(definition) with a Definition whose target (and therefore buildViewNode) is undefined — reusing an ordinary match/update Definition object as the fallback, or a construction path that conditionally omits the pair.

Common situations: Refactoring a plugin and moving its generic renderer to the fallback while keeping the old match-based shape; test fixtures building minimal Definition objects without the target pair; a partial-object spread dropping optional-looking fields.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/55a89690a85fe603. Report an issue: GitHub.