{"record":{"id":"e80ddbe4ada31d8d","repo":"cayleygraph/cayley","slug":"unmarshal-value-w","errorCode":null,"errorMessage":"unmarshal value: %w","messagePattern":"unmarshal value: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/sql/quadstore.go","lineNumber":726,"sourceCode":"\t\t\tval = quad.TypedString{\n\t\t\t\tValue: quad.String(unescapeNullByte(str.String)),\n\t\t\t\tType:  quad.IRI(typ.String),\n\t\t\t}\n\t\t} else {\n\t\t\tval = quad.String(unescapeNullByte(str.String))\n\t\t}\n\t} else if vint.Valid {\n\t\tval = quad.Int(vint.Int64)\n\t} else if vbool.Valid {\n\t\tval = quad.Bool(vbool.Bool)\n\t} else if vfloat.Valid {\n\t\tval = quad.Float(vfloat.Float64)\n\t} else if *vtimeValid {\n\t\tval = quad.Time(vtimeTime.UTC())\n\t} else {\n\t\tqv, err := pquads.UnmarshalValue(data)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unmarshal value: %w\", err)\n\t\t}\n\t\tval = qv\n\t}\n\tif val != nil {\n\t\tqs.ids.Put(hash.String(), val)\n\t}\n\treturn val, nil\n}\n\nfunc (qs *QuadStore) Stats(ctx context.Context, exact bool) (graph.Stats, error) {\n\tst := graph.Stats{\n\t\tNodes: refs.Size{Exact: true},\n\t\tQuads: refs.Size{Exact: true},\n\t}\n\tqs.mu.RLock()\n\tst.Quads.Value = qs.quads\n\tst.Nodes.Value = qs.nodes\n\tqs.mu.RUnlock()","sourceCodeStart":708,"sourceCodeEnd":744,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/sql/quadstore.go#L708-L744","documentation":"When a stored value is neither a plain string, bool, int, float, nor time, the SQL quadstore falls back to pquads.UnmarshalValue on the protobuf blob column to rebuild the quad.Value. If that protobuf blob cannot be unmarshaled, this wrapped error is returned.","triggerScenarios":"The `data` protobuf column is empty, truncated, or written by an incompatible version whose protobuf schema differs; corrupt rows in the values table.","commonSituations":"Restoring a dump from an older/newer Cayley version with a changed proto schema; manual DB edits; interrupted writes leaving partial blobs.","solutions":["Check the wrapped error to see if the blob is empty or malformed","Verify the data was written by a compatible version of the quadstore/proto schema","Re-import the affected data from source RDF/quads","Delete corrupt rows and let the store rebuild from an authoritative dataset"],"exampleFix":"// before\n// data column written by old schema\nqs.NameOf(h) // unmarshal value: proto: wrong wireType ...\n// after\n// re-export and re-load data with matching cayley version before querying","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"val, err := qs.NameOf(h)\nif err != nil && strings.Contains(err.Error(), \"unmarshal value\") {\n    // treat row as corrupt: log hash, skip or trigger re-import\n}","preventionTips":["Never edit protobuf blob columns manually","Use matching library versions for import and export","Back up and re-import from source data if corruption is suspected"],"tags":["database","sql","protobuf","data-corruption"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}