{"record":{"id":"45130b98d959c722","repo":"cayleygraph/cayley","slug":"v-fields-are-not-supported","errorCode":null,"errorMessage":"%v fields are not supported","messagePattern":"(.+?) fields are not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/schema.go","lineNumber":211,"sourceCode":"\tif ps == \"\" {\n\t\treturn nil, fmt.Errorf(\"wrong quad format: '%s': no predicate\", rule)\n\t}\n\tp := c.toIRI(ps)\n\tif vs == \"\" || vs == any && fld.Type != reflEmptyStruct {\n\t\treturn saveRule{Pred: p, Rev: rev, Opt: opt}, nil\n\t}\n\treturn constraintRule{Pred: p, Val: c.toIRI(vs), Rev: rev}, nil\n}\n\nfunc checkFieldType(ftp reflect.Type) error {\n\tfor ftp.Kind() == reflect.Ptr || ftp.Kind() == reflect.Slice {\n\t\tftp = ftp.Elem()\n\t}\n\tswitch ftp.Kind() {\n\tcase reflect.Array: // TODO: support arrays\n\t\treturn fmt.Errorf(\"array fields are not supported yet\")\n\tcase reflect.Func, reflect.Invalid:\n\t\treturn fmt.Errorf(\"%v fields are not supported\", ftp.Kind())\n\tdefault:\n\t}\n\treturn nil\n}\n\nvar (\n\ttypesMu   sync.RWMutex\n\ttypeToIRI = make(map[reflect.Type]quad.IRI)\n\tiriToType = make(map[quad.IRI]reflect.Type)\n)\n\nfunc getTypeIRI(rt reflect.Type) quad.IRI {\n\ttypesMu.RLock()\n\tiri := typeToIRI[rt]\n\ttypesMu.RUnlock()\n\treturn iri\n}\n","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/schema/schema.go#L193-L229","documentation":"checkFieldType rejects field types the schema generator cannot serialize: reflect.Func and reflect.Invalid kinds. The error message names the offending kind. It fires after unwrapping pointers and slices down to the element type.","triggerScenarios":"Calling Generate on a struct containing a func-typed field, or a nil/invalid reflect.Type reaching field inspection (e.g. interface{} fields resolving to invalid, or slice of untyped nil).","commonSituations":"Structs embedding callbacks, closures, or injected handler functions; fields of interface type whose element type is invalid; reflection bugs producing zero types.","solutions":["Remove or ignore the func/invalid-typed field from schema mapping (tag it out, e.g. `quad:\"-\"`)","Move function fields out of the data struct into a separate runtime-only struct","Ensure interface-typed fields have a concrete, serializable type before Generate"],"exampleFix":"// before\ntype Doc struct {\n    OnSave func()\n}\n// after\ntype Doc struct {\n    OnSave func() `quad:\"-\"`\n}","handlingStrategy":"validation","validationCode":"func hasFuncField(v interface{}) bool {\n    t := reflect.TypeOf(v)\n    if t.Kind() == reflect.Ptr { t = t.Elem() }\n    for i := 0; i < t.NumField(); i++ {\n        k := t.Field(i).Type.Kind()\n        if k == reflect.Func || k == reflect.Invalid { return true }\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":"if err := schema.Generate(c, Doc{}); err != nil {\n    if strings.Contains(err.Error(), \"fields are not supported\") {\n        // remove/ignore the offending func field\n    }\n    return err\n}","preventionTips":["Keep behavior (functions) out of data structs persisted to the graph","Ignore func fields with the schema ignore tag","Validate all schema types at startup"],"tags":["schema","reflection","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}