wavetermdev/waveterm · error

cannot convert %T to %s (idx %d) error: %v

Error message

cannot convert %T to %s (idx %d) error: %v

What it means

After each element of a []waveobj.WaveObj argument passes the is-a-map check, it is decoded with waveobj.FromJsonMap. If FromJsonMap fails (e.g. missing/invalid otype, unknown object type, malformed fields), convertSpecial wraps the inner error with the argument type and element index, so a single bad element fails the whole call.

Source

Thrown at pkg/service/service.go:144

	} else if argType == waveObjRType {
		if jsonType.Kind() != reflect.Map {
			return nil, fmt.Errorf("cannot convert %T to %s", jsonArg, argType)
		}
		return waveobj.FromJsonMap(jsonArg.(map[string]any))
	} else if argType == waveObjSliceRType {
		if jsonType.Kind() != reflect.Slice {
			return nil, fmt.Errorf("cannot convert %T to %s", jsonArg, argType)
		}
		sliceArg := jsonArg.([]any)
		nativeSlice := make([]waveobj.WaveObj, len(sliceArg))
		for idx, elem := range sliceArg {
			elemMap, ok := elem.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("cannot convert %T to %s (idx %d is not a map, is %T)", jsonArg, waveObjSliceRType, idx, elem)
			}
			nativeObj, err := waveobj.FromJsonMap(elemMap)
			if err != nil {
				return nil, fmt.Errorf("cannot convert %T to %s (idx %d) error: %v", jsonArg, waveObjSliceRType, idx, err)
			}
			nativeSlice[idx] = nativeObj
		}
		return nativeSlice, nil
	} else if argType == waveObjMapRType {
		if jsonType.Kind() != reflect.Map {
			return nil, fmt.Errorf("cannot convert %T to %s", jsonArg, argType)
		}
		mapArg := jsonArg.(map[string]any)
		nativeMap := make(map[string]waveobj.WaveObj)
		for key, elem := range mapArg {
			elemMap, ok := elem.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("cannot convert %T to %s (key %s is not a map, is %T)", jsonArg, waveObjMapRType, key, elem)
			}
			nativeObj, err := waveobj.FromJsonMap(elemMap)
			if err != nil {
				return nil, fmt.Errorf("cannot convert %T to %s (key %s) error: %v", jsonArg, waveObjMapRType, key, err)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Read the wrapped inner error (%v) for the concrete FromJsonMap failure and fix the element at the reported idx accordingly.
  2. Ensure each element has valid "otype" and "oid" fields for a registered WaveObj type.
  3. Align frontend/backend versions so the otype and field schema match.
  4. Generate payloads via the client SDK's ToJsonMap/serialization helpers rather than hand-writing them.

Example fix

// before
callService("objservice", "UpdateObjects", [{ "otype": "block" }]) // missing oid
// after
callService("objservice", "UpdateObjects", [{ "otype": "block", "oid": "abc123", "meta": {}, "view": {} }])
Defensive patterns

Strategy: validation

Validate before calling

function validateWaveObjs(arr) { arr.forEach((e, i) => { if (typeof e.otype !== 'string' || typeof e.oid !== 'string') throw new Error('element ' + i + ' missing otype/oid'); }); }

Type guard

function hasWaveObjMeta(e) { return e && typeof e.otype === 'string' && typeof e.oid === 'string'; }

Try / catch

try { return await callService(svc, method, args); } catch (e) { const m = String(e).match(/idx (\d+)\) error: (.*)$/); if (m) { console.error('WaveObj at index ' + m[1] + ' failed decode: ' + m[2]); } throw e; }

Prevention

When it happens

Trigger: An RPC call whose WaveObj-slice argument contains an object at idx that FromJsonMap rejects: missing "otype"/"oid" keys, an unrecognized otype string, or otype-specific fields failing validation.

Common situations: Hand-crafted or partially-populated object payloads (e.g. {"otype":"block"} with no oid); an otype added in a newer frontend but unknown to an older backend; renamed or removed object fields after a schema update.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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