{"record":{"id":"ca67cb7df7139d08","repo":"plandex-ai/plandex","slug":"error-marshalling-convo-message-description-v","errorCode":null,"errorMessage":"error marshalling convo message description: %v","messagePattern":"error marshalling convo message description: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/plan_helpers.go","lineNumber":340,"sourceCode":"\t\t}\n\t\tif op.Description != \"\" {\n\t\t\tquoted := strconv.Quote(op.Description)\n\t\t\top.Description = quoted[1 : len(quoted)-1]\n\t\t}\n\t}\n\n\tnow := time.Now()\n\n\tif description.Id == \"\" {\n\t\tdescription.Id = uuid.New().String()\n\t\tdescription.CreatedAt = now\n\t}\n\tdescription.UpdatedAt = now\n\n\tbytes, err := json.Marshal(description)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshalling convo message description: %v\", err)\n\t}\n\n\terr = os.WriteFile(filepath.Join(descriptionsDir, description.Id+\".json\"), bytes, os.ModePerm)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing convo message description: %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc DeleteDraftPlans(orgId, projectId, userId string) error {\n\tres, err := Conn.Query(\"DELETE FROM plans WHERE project_id = $1 AND owner_id = $2 AND name = 'draft' RETURNING id;\", projectId, userId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error deleting draft plans: %v\", err)\n\t}\n\n\tdefer res.Close()","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/plan_helpers.go#L322-L358","documentation":"This error means json.Marshal failed while serializing a ConvoMessageDescription before it is written to disk. Marshaling of plain structs rarely fails, so this usually indicates unsupported types in the description payload (e.g. channels, funcs, or cyclic data in custom fields).","triggerScenarios":"json.Marshal(description) returns an error because the struct contains an unmarshalable value: a channel, function field, cyclic pointer graph, or an unsupported type added to ConvoMessageDescription/Operation structs.","commonSituations":"A developer added a new field of unsupported type (chan, sync.Mutex used as value, func) to the description struct; a custom MarshalJSON panics or errors; embedding a runtime-built object containing cycles.","solutions":["Inspect the wrapped error for the offending field path and remove or retype it","Change unsupported fields (chan/func) to serializable representations (string IDs, byte slices)","Add json:\"-\" tags to internal-only fields that must not be marshaled","Add a unit test marshaling a fully populated ConvoMessageDescription"],"exampleFix":"// before\ntype ConvoMessageDescription struct {\n    Operations []Operation\n    Done       chan struct{}\n}\n// after\ntype ConvoMessageDescription struct {\n    Operations []Operation\n    Done       chan struct{} `json:\"-\"`\n}","handlingStrategy":"try-catch","validationCode":"func isMarshalable(v any) error {\n    _, err := json.Marshal(v)\n    return err\n}\n// call isMarshalable(description) before StoreDescription","typeGuard":null,"tryCatchPattern":"if err := StoreDescription(desc); err != nil {\n    if strings.Contains(err.Error(), \"unsupported type\") {\n        // offending field in struct; fix struct tags/types\n    }\n    return err\n}","preventionTips":["Keep chan/func/mutex fields out of persisted structs or tag them json:\"-\"","Add a unit test that marshals a fully populated description","Avoid cyclic references in description payloads"],"tags":["json","serialization","go"],"backgroundTag":"json-marshal-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}