dgraph-io/dgraph · error
Value for predicate <dgraph.rule.permission> should be of ty
Error message
Value for predicate <dgraph.rule.permission> should be of type int
What it means
When ACLs are enabled, the internal predicate dgraph.rule.permission stores a permission bitmask (0-7) per (group, predicate) rule. ValidateAndConvert checks every mutation of this predicate and rejects it if the converted value is not an int64, since only integers form a valid permission mask.
Source
Thrown at worker/mutation.go:577
)
src := types.Val{Tid: types.TypeID(edge.ValueType), Value: edge.Value}
// check compatibility of schema type and storage type
// The goal is to convert value on edge to value type defined by schema.
if dst, err = types.Convert(src, schemaType); err != nil {
return err
}
// convert to schema type
b := types.ValueForType(types.BinaryID)
if err = types.Marshal(dst, &b); err != nil {
return err
}
if x.WorkerConfig.AclEnabled && x.ParseAttr(edge.GetAttr()) == "dgraph.rule.permission" {
perm, ok := dst.Value.(int64)
if !ok {
return errors.Errorf("Value for predicate <dgraph.rule.permission> should be of type int")
}
if perm < 0 || perm > 7 {
return errors.Errorf("Can't set <dgraph.rule.permission> to %d, Value for this"+
" predicate should be between 0 and 7", perm)
}
}
// TODO: Figure out why this is Enum. It really seems like an odd choice -- rather than
// specifying it as the same type as presented in su.
edge.ValueType = schemaType.Enum()
var ok bool
edge.Value, ok = b.Value.([]byte)
if !ok {
return errors.Errorf("failure to convert edge type: '%+v' to schema type: '%+v'",
storageType, schemaType)
}
return nilView on GitHub (pinned to 759e242be6)
Solutions
- Send the permission as an integer, e.g. {"set":[{"uid":"0x...","dgraph.rule.permission":5}]}.
- Convert string/float values to int64 before submitting the ACL mutation (e.g. int(value) in the script).
- Confirm ACL is truly enabled (x.WorkerConfig.AclEnabled); if you did not intend to touch ACL internals, use the intended predicate instead.
Example fix
// before (fails)
{"set":[{"uid":"0x1","dgraph.rule.permission":"5"}]}
// after
{"set":[{"uid":"0x1","dgraph.rule.permission":5}]} Defensive patterns
Strategy: type-guard
Validate before calling
function assertAclPermissionInt(value) {
if (!Number.isInteger(value)) {
throw new TypeError(`dgraph.rule.permission must be an integer, got ${typeof value}: ${value}`)
}
} Type guard
function isInt64(v) {
return typeof v === 'number' && Number.isInteger(v) && v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER
} Try / catch
try {
await aclClient.modifyPermissions(rule)
} catch (e) {
if (String(e).includes('should be of type int')) {
// coerce to int and re-submit
}
} Prevention
- Never quote numeric permission values in JSON mutations.
- Parse ACL config files with integer-typed fields (avoid YAML/JSON float coercion).
- Wrap ACL mutations in helper functions that validate input types.
When it happens
Trigger: A mutation (executed via runMutation -> proposeAndWait, typically through the ACL APIs or @group directives) sets dgraph.rule.permission to a non-int value, e.g. a float, string, or bool because the value was sent as "5" (string) or 5.0 (float) in JSON.
Common situations: Automation scripts that read ACL rules from JSON/YAML where numbers deserialize as float or string; hand-written JSON mutations that quote the number; ACL tooling bugs.
Related errors
- UID must be present and non-zero while deleting edges
- facet value can only be string/number/bool
- facets format should be of type map for scalarlist predicate
- Multiple groot users found
- Error while parsing Uid: %s of groot user
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/f92c0a4eac62619b.
Report an issue: GitHub.