wavetermdev/waveterm · error

waveid is required

Error message

waveid is required

What it means

handleTermInput requires the parsed VDomEvent to carry a non-blank WaveId identifying which wave/block the terminal input targets. If event.WaveId is empty or whitespace-only after TrimSpace, it returns 400 'waveid is required'.

Source

Thrown at tsunami/engine/serverhandlers.go:424

	if r.Method != http.MethodPost {
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}

	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to read request body: %v", err), http.StatusBadRequest)
		return
	}

	var event vdom.VDomEvent
	if err := json.Unmarshal(body, &event); err != nil {
		http.Error(w, fmt.Sprintf("failed to parse JSON: %v", err), http.StatusBadRequest)
		return
	}
	if strings.TrimSpace(event.WaveId) == "" {
		http.Error(w, "waveid is required", http.StatusBadRequest)
		return
	}
	if event.TermInput == nil {
		http.Error(w, "terminput is required", http.StatusBadRequest)
		return
	}

	h.renderLock.Lock()
	h.Client.Root.Event(event, h.Client.GlobalEventHandler)
	h.renderLock.Unlock()

	w.WriteHeader(http.StatusNoContent)
}

func (h *httpHandlers) handleDynContent(w http.ResponseWriter, r *http.Request) {
	defer func() {
		panicErr := util.PanicHandler("handleDynContent", recover())
		if panicErr != nil {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set the waveId field in the JSON payload to the target wave's id
  2. Check the client that produces the event actually propagates the current wave id
  3. Use the wave id shown in the running session rather than a hardcoded placeholder
  4. Add a client-side assertion on waveId before POSTing

Example fix

// before
{"termInput":{"inputData":"ls\n"}}
// after
{"waveId":"wave-1234-abcd","termInput":{"inputData":"ls\n"}}
Defensive patterns

Strategy: validation

Validate before calling

if (!event.waveId || !event.waveId.trim()) {
  throw new Error('waveid is required: set event.waveId before POSTing')
}

Type guard

function hasWaveId(e: unknown): e is { waveId: string } {
  return typeof (e as any)?.waveId === 'string' && (e as any).waveId.trim() !== ''
}

Try / catch

const res = await fetch(url, opts)
if (res.status === 400 && (await res.text()).includes('waveid is required')) {
  // recover: re-acquire current wave id and rebuild the event
}

Prevention

When it happens

Trigger: POSTing a JSON event whose waveId field is missing, null, empty string, or only whitespace; constructing VDomEvent programmatically without setting WaveId.

Common situations: Scripts replaying events from logs where waveId was stripped; frontend bugs not binding the active wave id; template payloads with placeholder values left empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/35877c8338444f70. Report an issue: GitHub.