{"record":{"id":"53c999d7f374aacc","repo":"vxcontrol/pentagi","slug":"knowledge-marshal-cmetadata-w","errorCode":null,"errorMessage":"knowledge: marshal cmetadata: %w","messagePattern":"knowledge: marshal cmetadata: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/database/knowledge/knowledge.go","lineNumber":505,"sourceCode":"\tmeta.PartSize = len(content)\n\tmeta.TotalSize = len(content)\n\n\t// Truncate to embedding size limit for vector computation; full content goes to DB.\n\tembeddingText := content\n\tif len(embeddingText) > ks.maxEmbeddingBytes {\n\t\tembeddingText = embeddingText[:ks.maxEmbeddingBytes]\n\t}\n\tvecs, err := ks.embedder.EmbedDocuments(ctx, []string{embeddingText})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"knowledge: compute embedding: %w\", err)\n\t}\n\tif len(vecs) == 0 {\n\t\treturn nil, fmt.Errorf(\"knowledge: embedder returned no vectors\")\n\t}\n\n\tcmJSON, err := metaToJSON(meta)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"knowledge: marshal cmetadata: %w\", err)\n\t}\n\n\tid := uuid.New()\n\tdocID, err := ks.db.InsertKnowledgeDocument(ctx, database.InsertKnowledgeDocumentParams{\n\t\tUuid:      id,\n\t\tDocument:  nsOf(content),\n\t\tEmbedding: formatVector(vecs[0]),\n\t\tCmetadata: cmJSON.RawMessage,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"knowledge: create document: %w\", err)\n\t}\n\n\tdoc := metaToModelDoc(docID, content, meta)\n\tks.newKnp(userID).KnowledgeDocumentCreated(ctx, doc)\n\treturn doc, nil\n}\n","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/database/knowledge/knowledge.go#L487-L523","documentation":"CreateDocument serializes the knowledgeMeta struct to JSON for the cmetadata column via metaToJSON. This should only fail for unsupported field values (e.g. non-marshalable types if meta is extended), and the error is wrapped as 'knowledge: marshal cmetadata'.","triggerScenarios":"metaToJSON returning an error — practically only when the metadata contains values json.Marshal cannot handle (channels, funcs, cyclic references) after custom extensions to knowledgeMeta or callers injecting raw metadata.","commonSituations":"A developer extends cmetadata with a custom type lacking JSON marshaling; passing a map containing NaN/Inf floats or nested unmarshalable values.","solutions":["Inspect the wrapped json error; it names the offending field/type.","Ensure all cmetadata values are JSON-safe primitives (string, number, bool, nil).","Add a unit test for metaToJSON with the new metadata shape before extending knowledgeMeta.","If using a map-based metadata path, sanitize/convert values with a normalization step before marshaling."],"exampleFix":"// before\ncmJSON, err := metaToJSON(meta) // fails on unmarshalable value\n// after\nsafe := make(map[string]any, len(meta))\nfor k, v := range meta {\n    switch v.(type) {\n    case string, bool, float64, int64, nil:\n        safe[k] = v\n    default:\n        safe[k] = fmt.Sprintf(\"%v\", v)\n    }\n}\ncmJSON, err := metaToJSON(safe)","handlingStrategy":"validation","validationCode":"if _, err := json.Marshal(meta); err != nil {\n    return nil, fmt.Errorf(\"invalid metadata: %w\", err)\n}","typeGuard":"func isJSONMarshalErr(err error) bool {\n    var je *json.UnsupportedTypeError\n    var nfe *json.UnsupportedValueError\n    return errors.As(err, &je) || errors.As(err, &nfe)\n}","tryCatchPattern":"doc, err := store.CreateDocument(ctx, userID, input)\nif err != nil {\n    if isJSONMarshalErr(err) {\n        return fmt.Errorf(\"metadata contains unsupported values: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep cmetadata restricted to JSON-safe primitive fields.","Add unit tests for metaToJSON whenever knowledgeMeta changes.","Sanitize any caller-supplied metadata map before storing.","Disallow NaN/Inf and non-serializable types at the input boundary."],"tags":["json","serialization","metadata"],"backgroundTag":"json-marshal-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}