dgraph-io/dgraph · error

Unsupported types.Val.Tid

Error message

Unsupported types.Val.Tid

What it means

valToBytes switches on the scalar type ID (types.Val.Tid) of a value when encoding query output. If the type ID is not one of the handled scalar kinds (default branch), Dgraph does not know how to serialize it and returns this error — usually meaning an unhandled or corrupted value type reached the output encoder.

Source

Thrown at query/outputnode.go:694

			return boolTrue, nil
		}
		return boolFalse, nil
	case types.DateTimeID:
		t := v.Value.(time.Time)
		return marshalTimeJson(t)
	case types.GeoID:
		return geojson.Marshal(v.Value.(geom.T))
	case types.BigFloatID:
		b := v.Value.(big.Float)
		return b.MarshalText()
	case types.UidID:
		return []byte(fmt.Sprintf("\"%#x\"", v.Value)), nil
	case types.PasswordID:
		return []byte(fmt.Sprintf("%q", v.Value.(string))), nil
	case types.VFloatID:
		return json.Marshal(v.Value.([]float32))
	default:
		return nil, errors.New("Unsupported types.Val.Tid")
	}
}

// marshalTimeJson does what time.MarshalJson does along with supporting RFC3339 non compliant
// time zones in a timestamp. While go 1.20 changes the behaviour of time.MarshalJSON, we do
// not want to throw error suddenly because we can't marshal the stored data correctly any more.
func marshalTimeJson(t time.Time) ([]byte, error) {
	_, offset := t.Zone()
	// normal case
	if types.GoodTimeZone(offset) {
		return t.MarshalJSON()
	}

	// If zone >23 or <-23, we need to handle this case ourselves.
	// This is because, in go1.20, MarshalJSON fails for invalid zones.
	// We, for now, call MarshalJSON for timestamp without the zone (or making it UTC zone).
	b, err := t.Add(time.Duration(offset) * time.Second).UTC().MarshalJSON()
	if err != nil {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Upgrade Dgraph to the latest patch release where more scalar types have encoder cases
  2. Inspect the predicate's schema (schema {}) and re-type or re-write the offending values via mutation
  3. Identify the affected node/predicate by bisecting the query, then delete and re-mutate the value with a supported scalar type
  4. If embedding the query package, add a case for the missing types ID in valToBytes

Example fix

// before
// query on predicate with unsupported stored type
{
  q(func: has(mypred)) { mypred }
}
// after: normalize the stored value first via mutation to a supported type (e.g. string/float), then query
Defensive patterns

Strategy: try-catch

Validate before calling

const schema = await dgraph.schema('mypred');
if (!['string','float','int','bool','datetime','default'].includes(schema[0]?.type)) throw new Error('unsupported predicate type for output');

Type guard

function isSupportedScalarType(tid: string): boolean {
  return ['string','int','float','bool','datetime','password','default'].includes(tid);
}

Try / catch

try {
  return await dgraph.query(q);
} catch (e) {
  if (String(e).includes('Unsupported types.Val.Tid')) {
    // fall back to fetching uid only, then re-read values with a supported-typed query
  }
  throw e;
}

Prevention

When it happens

Trigger: A predicate's stored value type has no JSON encoder case in valToBytes (e.g. a newly added or internal-only types.Val Tid), or schema/type coercion produced a Val with an unexpected Tid passed through getObjectVal or AddListValue.

Common situations: Dgraph version upgrades introducing new types not handled by older encoder code paths; schema migrations leaving values with mismatched type IDs; programmatic use of the internal types package constructing a Val with an invalid Tid.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/4db60dafa95237e5. Report an issue: GitHub.