{"record":{"id":"9d0250339f84f0e8","repo":"cayleygraph/cayley","slug":"unsupported-type-for-id-field-t","errorCode":null,"errorMessage":"unsupported type for id field: %T","messagePattern":"unsupported type for id field: %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"schema/schema.go","lineNumber":450,"sourceCode":"\treturn rv.Interface() == reflect.Zero(rv.Type()).Interface()\n}\n\nfunc (c *Config) idFor(rules fieldRules, rt reflect.Type, rv reflect.Value, pref string) (id quad.Value, err error) {\n\thasAnon := false\n\tfor i := 0; i < rt.NumField(); i++ {\n\t\tfld := rt.Field(i)\n\t\thasAnon = hasAnon || fld.Anonymous\n\t\tif _, ok := rules[pref+fld.Name].(idRule); ok {\n\t\t\tvid := rv.Field(i).Interface()\n\t\t\tswitch vid := vid.(type) {\n\t\t\tcase quad.IRI:\n\t\t\t\tid = c.iri(vid)\n\t\t\tcase quad.BNode:\n\t\t\t\tid = vid\n\t\t\tcase string:\n\t\t\t\tid = c.toIRI(vid)\n\t\t\tdefault:\n\t\t\t\terr = fmt.Errorf(\"unsupported type for id field: %T\", vid)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tif !hasAnon {\n\t\treturn\n\t}\n\t// second pass - look for anonymous fields\n\tfor i := 0; i < rt.NumField(); i++ {\n\t\tfld := rt.Field(i)\n\t\tif !fld.Anonymous {\n\t\t\tcontinue\n\t\t}\n\t\tid, err = c.idFor(rules, fld.Type, rv.Field(i), pref+fld.Name+\".\")\n\t\tif err != nil || id != nil {\n\t\t\treturn\n\t\t}\n\t}","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/schema/schema.go#L432-L468","documentation":"When computing a node ID for a struct instance, the idFor machinery accepts quad.IRI, quad.BNode, and string values for the id field. Any other Go type stored in the id field cannot be converted to a node identifier, so this error is returned. It propagates out of configFrom/open when loading a schema config that specifies an id field of an unsupported type.","triggerScenarios":"Configuring an id field (via Config or the appengine configFrom path) whose runtime value is, e.g., an int, float, struct, or other non-string/non-quad type; idFor then hits the default branch and fails.","commonSituations":"Using int or int64 auto-increment IDs in structs mapped with an id tag; loading a JSON schema config whose id type doesn't match what the loader expects.","solutions":["Change the id field to a string (or quad.IRI/quad.BNode) type","Convert the value to string before it reaches schema ID generation (e.g. strconv.FormatInt)","Implement a custom ID method (ID() quad.IRI or similar supported hook) on the struct"],"exampleFix":"// before\ntype Doc struct {\n    ID   int64 `quad:\"@id\"`\n}\n// after\ntype Doc struct {\n    ID   string `quad:\"@id\"`\n}","handlingStrategy":"type-guard","validationCode":"switch id := doc.ID.(type) {\ncase string, quad.IRI, quad.BNode:\n    // ok\ndefault:\n    return fmt.Errorf(\"id field must be string/IRI/BNode, got %T\", id)\n}","typeGuard":"func validID(v interface{}) bool {\n    switch v.(type) {\n    case string, quad.IRI, quad.BNode:\n        return true\n    }\n    return false\n}","tryCatchPattern":"if _, err := w.WriteAsQuads(qs, doc); err != nil {\n    if strings.Contains(err.Error(), \"unsupported type for id field\") {\n        return fmt.Errorf(\"convert doc.ID to string before writing: %w\", err)\n    }\n    return err\n}","preventionTips":["Type the id field as string or quad.IRI in mapped structs","Convert numeric IDs with strconv before writing","Prefer implementing an ID() hook for computed identifiers"],"tags":["schema","identifier","type-mismatch"],"backgroundTag":"invalid-argument-value","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"}