wavetermdev/waveterm · error

cannot convert %T to

Error message

cannot convert %T to %s (key %s) error: %v

What it means

For map[string]waveobj.WaveObj arguments, each map value that passes the object check is decoded with waveobj.FromJsonMap. If decoding fails for any value (missing otype/oid, unknown otype, invalid fields), the whole call fails with this error, which names the failing key and wraps the underlying FromJsonMap error.

Solutions

  1. Read the wrapped inner error and fix the WaveObj stored under the reported key (usually missing/invalid otype or oid).
  2. Ensure every map value carries valid "otype" and "oid" for a registered WaveObj type.
  3. Synchronize client and server versions so otype names and field schemas match.
  4. Build payloads with the SDK serialization helpers (ToJsonMap) instead of hand-assembling maps.

Example fix

// before
callService("objservice", "SetObjects", { "main": { "otype": "tab" } }) // missing oid
// after
callService("objservice", "SetObjects", { "main": { "otype": "tab", "oid": "xyz789", "meta": {} } })
Defensive patterns

Strategy: validation

Validate before calling

for (const [k, v] of Object.entries(arg)) { if (typeof v?.otype !== 'string' || typeof v?.oid !== 'string') throw new Error('map value at key ' + k + ' missing valid otype/oid'); }

Type guard

function isValidWaveObj(v) { return v && typeof v.otype === 'string' && typeof v.oid === 'string'; }

Try / catch

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

Prevention

When it happens

Trigger: An RPC call with a WaveObj map argument where the value at some key is an object but malformed: absent "otype"/"oid", an otype the server doesn't know, or fields failing otype-specific validation.

Common situations: Partially constructed objects placed into maps; an otype introduced in a newer client unknown to an older backend; field renames after a schema migration leaving payloads invalid.

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/8655da31aee82606. Report an issue: GitHub.

Appendix: source

Thrown at pkg/service/service.go:162

				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)
			}
			nativeMap[key] = nativeObj
		}
		return nativeMap, nil
	} else {
		return nil, fmt.Errorf("invalid special wave argument type %s", argType)
	}
}

func convertSpecialForReturn(argType reflect.Type, nativeArg any) (any, error) {
	if argType == waveObjRType {
		return waveobj.ToJsonMap(nativeArg.(waveobj.WaveObj))
	} else if argType == waveObjSliceRType {
		nativeSlice := nativeArg.([]waveobj.WaveObj)
		jsonSlice := make([]map[string]any, len(nativeSlice))
		for idx, elem := range nativeSlice {
			elemMap, err := waveobj.ToJsonMap(elem)
			if err != nil {

View on GitHub (pinned to a4447c1563)