ent/ent · error
GoType must be a %q type, ValueScanner or provide an externa
Error message
GoType must be a %q type, ValueScanner or provide an external ValueScanner
What it means
Schema-definition error from Descriptor.checkGoType in the default branch: the field's Go type is neither the expected built-in type nor a ValueScanner implementation, and no external ValueScanner was provided on the descriptor. The message names the expected type — the field's GoType must be that type, implement ValueScanner itself, or be paired with an external ValueScanner via the schema API.
Source
Thrown at schema/field/field.go:1497
m1, ok1 := vs.MethodByName("Value")
m2, ok2 := vs.MethodByName("ScanValue")
m3, ok3 := vs.MethodByName("FromValue")
switch {
case !ok1, m1.Type.NumIn() != 2, m1.Type.In(1) != t,
m1.Type.NumOut() != 2, m1.Type.Out(0) != valueType, m1.Type.Out(1) != errorType:
d.Err = fmt.Errorf("ValueScanner must implement the Value method: func Value(%s) (driver.Valuer, error)", t)
case !ok2, m2.Type.NumIn() != 1, m2.Type.NumOut() != 1, m2.Type.Out(0) != valueScannerType:
d.Err = errors.New("ValueScanner must implement the ScanValue method: func ScanValue() field.ValueScanner")
case !ok3, m3.Type.NumIn() != 2, m3.Type.In(1) != valueType, m3.Type.NumOut() != 2, m3.Type.Out(0) != t, m3.Type.Out(1) != errorType:
d.Err = fmt.Errorf("ValueScanner must implement the FromValue method: func FromValue(driver.Valuer) (%s, error)", t)
}
// No GoType was provided.
case d.Info.RType == nil:
// A GoType without an external ValueScanner.
case pt.Implements(valueScannerType), t.Implements(valueScannerType), t.Kind() == expectType.Kind() && t.ConvertibleTo(expectType):
// There is a GoType, but it's not a ValueScanner.
default:
d.Err = fmt.Errorf("GoType must be a %q type, ValueScanner or provide an external ValueScanner", expectType)
}
}
// pkgName returns the package name from a Go
// identifier with a package qualifier.
func pkgName(ident string) string {
i := strings.LastIndexByte(ident, '.')
if i == -1 {
return ""
}
s := ident[:i]
if i := strings.LastIndexAny(s, "]*"); i != -1 {
s = s[i+1:]
}
return s
}
func methods(t reflect.Type, rtype *RType) {View on GitHub (pinned to 69d5d4deb1)
Solutions
- Set the field's GoType to the expected concrete type, or make it implement Value/Scan (driver.Valuer/sql.Scanner)
- Provide an external implementation via the ValueScanner option so checkGoType can validate its methods
- For custom types over built-ins, use the generic field.ValueScanner[T] helpers in schema/field
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at schema/field/field.go:1497 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ent/ent@69d5d4deb1 (2026-09-03).
Data as JSON: /api/errors/999f03ddaca29def.
Report an issue: GitHub.