deepseek-ai/deepseek-harness · error

no serializer for reference source "${o.source}"

Error message

no serializer for reference source "${o.source}"

What it means

Before sinking a submit, the input facade expands every inline reference occurrence (mention chips) into its model form via the inputTriggers service's serializeReference. inputTriggers is an optional injected dependency (deps.inputTriggers?.()); if it is not wired while the draft contains occurrences, no serializer exists for the occurrence's source and the submit is aborted with this error. The code deliberately refuses a silent downgrade to the clipboard text: the notice shows and the draft plus chips are retained.

Source

Thrown at packages/client/ui-conversation/src/client/input/facade.ts:466

  /**
   * Prompt serialization before the sink: expand each
   * inline reference range to its owner's model form via the session controller's
   * codec routing. Owner missing / serialize failure / disposal blocks the
   * send — notice + draft and chips retained, never a silent downgrade to
   * the clipboard text. Chip-free drafts skip the async detour.
   */
  private sinkSerialized(attempt: SubmitAttempt, draft: string, mode: InputSubmitMode): void {
    const imageIds = [...this.imageIds]
    const occurrences = this.core.state.occurrences
    if (occurrences.length === 0) {
      this.settleSubmit(attempt, this.deps.defaultSink(draft.trim(), imageIds, mode, attempt.signal), imageIds)
      return
    }
    const inputTriggers = this.deps.inputTriggers?.()
    const controller = new AbortController()
    void Promise.all(occurrences.map(async (o) => {
      if (inputTriggers === undefined) throw new Error(`no serializer for reference source "${o.source}"`)
      return {
        offset: o.offset,
        length: o.length,
        text: await inputTriggers.serializeReference(o.source, o.ref, controller.signal),
      }
    })).then(
      (parts) => {
        if (this.disposed) return
        // Splice model forms over their display ranges (offsets are draft-time;
        // parts arrive offset-sorted since the table is).
        let out = ''
        let cursor = 0
        for (const part of parts) {
          out += draft.slice(cursor, part.offset) + part.text
          cursor = part.offset + part.length
        }
        out += draft.slice(cursor)
        this.settleSubmit(attempt, this.deps.defaultSink(out.trim(), imageIds, mode, attempt.signal), imageIds)

View on GitHub (pinned to b150a551b8)

Solutions

  1. Register and provide the inputTriggers service — load the plugin that owns reference serialization — in the composition
  2. Clear the reference chips from the draft; a chip-free draft submits through the default sink without the serializer
  3. In tests, inject a stub inputTriggers whose serializeReference resolves

Example fix

// before: facade constructed without the trigger dependency
const facade = new InputFacade(core, { defaultSink, /* inputTriggers missing */ })
// after: wire the trigger source so chip drafts can serialize
const facade = new InputFacade(core, { defaultSink, inputTriggers: () => triggerService })
Defensive patterns

Strategy: validation

Validate before calling

const chips = coreSnapshot.occurrences
if (chips.length > 0 && inputTriggers?.() === undefined) {
  blockSubmit('reference chips require the input trigger plugin')
}

Type guard

function canSerializeReferences(deps: FacadeDeps): boolean {
  return deps.inputTriggers !== undefined && deps.inputTriggers() !== undefined
}

Prevention

When it happens

Trigger: A draft carrying reference chips (occurrences.length > 0) is submitted while deps.inputTriggers?.() returns undefined — the trigger provider plugin is not loaded or registered, failed activation, or a test constructed the facade without the dependency. Chip-free drafts skip the async detour entirely and never hit this.

Common situations: A custom embedder composing ui-conversation without the input-trigger provider plugin; a plugin load failure or composition regression after an upgrade; a persisted draft containing chips restored on a mount where the trigger plugin is absent.

Related errors


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