wavetermdev/waveterm · error

cannot convert special return value: %v

Error message

cannot convert special return value: %v

What it means

Set on the WebReturnType.Error field when convertSpecialForReturn fails to serialize a special Wave return value (WaveObj, []WaveObj, or map[string]WaveObj) back to JSON. This usually means waveobj.ToJsonMap failed on the object (bad/missing otype or missing required fields), or a method returned a nil/invalid object inside a slice or map.

Source

Thrown at pkg/service/service.go:297

	}
	for _, val := range rtnVals {
		if isNilable(val) && val.IsNil() {
			continue
		}
		valType := val.Type()
		if valType == errorRType {
			rtn.Error = val.Interface().(error).Error()
			continue
		}
		if valType == updatesRType {
			// has a special MarshalJSON method
			rtn.Updates = val.Interface().([]waveobj.WaveObjUpdate)
			continue
		}
		if isSpecialWaveArgType(valType) {
			jsonVal, err := convertSpecialForReturn(valType, val.Interface())
			if err != nil {
				rtn.Error = fmt.Errorf("cannot convert special return value: %v", err).Error()
				continue
			}
			rtn.Data = jsonVal
			continue
		}
		rtn.Data = val.Interface()
	}
	if rtn.Error == "" {
		rtn.Success = true
	}
	return rtn
}

func webErrorRtn(err error) *WebReturnType {
	return &WebReturnType{
		Error: err.Error(),
	}
}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the wrapped %v detail in rtn.Error — it carries the underlying ToJsonMap failure reason.
  2. Ensure returned WaveObj values have valid OType and OID set before returning.
  3. Register custom object types properly so FromJsonMap/ToJsonMap round-trip works.
  4. Return an error alongside the value so failures surface cleanly instead of only the conversion error.

Example fix

// before
func (s *Svc) GetObj() waveobj.WaveObj {
    return &MyObj{} // missing OType/OID
}

// after
func (s *Svc) GetObj() (waveobj.WaveObj, error) {
    return &MyObj{OType: "myobj", OID: genId()}, nil
}
Defensive patterns

Strategy: try-catch

Validate before calling

// server-side pre-check before returning
if (obj == nil || reflect.ValueOf(obj).IsNil() || obj.GetOType() == "") {
    return nil, fmt.Errorf("invalid WaveObj: missing otype")
}

Type guard

function isValidReturn(rtn) { return rtn != null && !('error' in rtn && rtn.error); }

Try / catch

const rtn = await callService(svc, method, args);
if (rtn.error?.startsWith('cannot convert special return value')) {
  // inspect rtn.error detail; re-request or surface serialization failure
}

Prevention

When it happens

Trigger: A service method returns waveobj.WaveObj (or slice/map of them) whose ToJsonMap conversion errors — e.g. an object with an empty OType/OID, or a WaveObj implementation failing serialization. The error is stored in rtn.Error rather than panicking, and the call is reported as failed to the client.

Common situations: Constructing WaveObj instances manually with missing otype/oid; custom obj types not registered with the waveobj schema; returning objects from a different waveobj package version than the serializer expects.

Related errors


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