dgraph-io/dgraph · error

Field in type definition must have a name

Error message

Field in type definition must have a name

What it means

typeSanityCheck validates each field in a pb.TypeUpdate. A field whose Predicate parses to an empty string via x.ParseAttr has no name, so Dgraph rejects the type update with this error. Every field in a type definition must reference a named predicate. It is raised from verifyTypes during type updates and is covered directly by TestTypeSanityCheck.

Source

Thrown at worker/mutation.go:822

			_, inSchema := schemaSet[fieldName]
			_, inRequest := reqPredSet[fieldName]
			if !inSchema && !inRequest {
				return errors.Errorf(
					"Schema does not contain a matching predicate for field %s in type %s",
					field.Predicate, t.TypeName)
			}
		}
	}

	return nil
}

// typeSanityCheck performs basic sanity checks on the given type update.
func typeSanityCheck(t *pb.TypeUpdate) error {
	for _, field := range t.Fields {
		if x.ParseAttr(field.Predicate) == "" {
			return errors.Errorf("Field in type definition must have a name")
		}

		if field.ValueType == pb.Posting_OBJECT && field.ObjectTypeName == "" {
			return errors.Errorf(
				"Field with value type OBJECT must specify the name of the object type")
		}

		if field.Directive != pb.SchemaUpdate_NONE {
			return errors.Errorf("Field in type definition cannot have a directive")
		}

		if len(field.Tokenizer) > 0 {
			return errors.Errorf("Field in type definition cannot have tokenizers")
		}
	}

	return nil
}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Ensure each field in the type definition has a real predicate name (`type Person { name }`, not an empty entry)
  2. Remove stray commas or blank lines from hand-written type blocks that yield anonymous fields
  3. Fix the code/generator that constructs TypeUpdate so Fields entries with empty Predicate are skipped or rejected before sending
  4. If namespaces are involved, verify the attribute includes its name after the namespace qualifier (ns@name, not just ns@)

Example fix

// before
{
  "types": [{
    "typeName": "Person",
    "fields": [{"predicate": ""}]
  }]
}

// after
{
  "types": [{
    "typeName": "Person",
    "fields": [{"predicate": "name"}]
  }]
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate every type field has a non-empty predicate name before sending
for _, t := range mutation.Types {
	for i, f := range t.Fields {
		if f.Predicate == "" {
			return fmt.Errorf("type %q field[%d] has empty predicate", t.TypeName, i)
		}
	}
}

Type guard

func fieldsNamed(t *api.TypeUpdate) bool {
	for _, f := range t.Fields {
		if f.Predicate == "" {
			return false
		}
	}
	return true
}

Try / catch

_, err := txn.Mutate(ctx, mu)
if err != nil && strings.Contains(err.Error(), "Field in type definition must have a name") {
	return fmt.Errorf("anonymous field in type definition: %w", err)
}

Prevention

When it happens

Trigger: A type update contains a field entry with an empty Predicate — e.g. a DQL type block with an empty line/trailing comma producing an anonymous field, or a programmatically built TypeUpdate with Fields entries whose Predicate is "" or a namespace-only attribute like "ns@" that ParseAttr reduces to empty.

Common situations: Generated schema payloads where the field-name variable is empty; hand-edited DQL leaving a stray comma in a type block; malformed JSON mutations with {"fields":[{"predicate":""}]}; incorrect namespace prefix handling that strips the actual attribute name.

Related errors


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