{"record":{"id":"b668e41a80f55856","repo":"Tencent/WeKnora","slug":"failed-to-generate-schema-v","errorCode":null,"errorMessage":"failed to generate schema: %v","messagePattern":"failed to generate schema: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/utils/json.go","lineNumber":24,"sourceCode":"\n\tjsonschema \"github.com/google/jsonschema-go/jsonschema\"\n)\n\n// ToJSON converts a value to a JSON string\nfunc ToJSON(v interface{}) string {\n\tjson, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\treturn string(json)\n}\n\n// GenerateSchema generates JSON schema for type T and returns it as a map\n// This is optimized to avoid unnecessary serialization/deserialization\nfunc GenerateSchema[T any]() json.RawMessage {\n\tschema, err := jsonschema.For[T](nil)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"failed to generate schema: %v\", err))\n\t}\n\n\t// Convert schema to map directly through JSON marshaling\n\t// This is necessary because the schema object doesn't expose its internal structure\n\tschemaBytes, err := json.Marshal(schema)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"failed to marshal schema: %v\", err))\n\t}\n\n\treturn schemaBytes\n}\n","sourceCodeStart":6,"sourceCodeEnd":36,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/json.go#L6-L36","documentation":"GenerateSchema[T] builds a JSON schema for the tool's input type using jsonschema.For[T](nil). If schema generation fails (e.g. the type uses constructs the generator cannot represent), it panics. This runs when tool definitions are built, so it is effectively a startup failure for the affected tool.","triggerScenarios":"Declaring a tool input struct that invopop/jsonschema cannot generate a schema for: unsupported field types (func, chan, complex), cycles without ref handling, invalid map key types, or generics instantiation producing an unsupported shape. Triggered by dataAnalysisTool, dataSchemaTool, databaseQueryTool, queryKnowledgeGraphTool, editSandboxFileTool, listSandboxFilesTool.","commonSituations":"Adding a field of an exotic type to a tool's request struct; a custom type without jsonschema-friendly tagging; upgrading the jsonschema library and hitting a new/changed limitation; embedding interfaces in tool parameter structs.","solutions":["Simplify or replace unsupported field types in the tool's input struct with JSON-representable types","Add struct tags (jsonschema:/json:) or a custom GenerateSchema override to guide generation","Pin/upgrade the jsonschema library to a version that supports the type in question","Wrap GenerateSchema at startup so the offending tool and type are named in logs"],"exampleFix":"// before\ntype input struct { Callback func(string) error `json:\"callback\"` }\n// after\ntype input struct { CallbackID string `json:\"callback_id\"` } // representable type","handlingStrategy":"validation","validationCode":"// sanity-check the input type is JSON-representable before tool init\nvar probe T\nb, err := json.Marshal(probe)\nif err != nil { return fmt.Errorf(\"type %T not JSON-representable: %w\", probe, err) }","typeGuard":"func schemaGeneratable[T any]() (ok bool) {\n    defer func() { _ = recover() }()\n    _ = utils.GenerateSchema[T]()\n    return true\n}","tryCatchPattern":"func schemaSafe[T any]() (raw json.RawMessage, err error) {\n    defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"schema panic: %v\", r) } }()\n    return utils.GenerateSchema[T](), nil\n}","preventionTips":["Keep tool input structs limited to JSON-representable field types","Validate new tool structs with a schema-generation unit test","Pin and review the jsonschema library version when adding exotic types"],"tags":["go","panic","json-schema","tools","reflection"],"backgroundTag":"schema-generation-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}