plandex-ai/plandex · error

error marshalling convo message description: %v

Error message

error marshalling convo message description: %v

What it means

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).

Source

Thrown at app/server/db/plan_helpers.go:340

		}
		if op.Description != "" {
			quoted := strconv.Quote(op.Description)
			op.Description = quoted[1 : len(quoted)-1]
		}
	}

	now := time.Now()

	if description.Id == "" {
		description.Id = uuid.New().String()
		description.CreatedAt = now
	}
	description.UpdatedAt = now

	bytes, err := json.Marshal(description)

	if err != nil {
		return fmt.Errorf("error marshalling convo message description: %v", err)
	}

	err = os.WriteFile(filepath.Join(descriptionsDir, description.Id+".json"), bytes, os.ModePerm)

	if err != nil {
		return fmt.Errorf("error writing convo message description: %v", err)
	}

	return nil
}

func DeleteDraftPlans(orgId, projectId, userId string) error {
	res, err := Conn.Query("DELETE FROM plans WHERE project_id = $1 AND owner_id = $2 AND name = 'draft' RETURNING id;", projectId, userId)
	if err != nil {
		return fmt.Errorf("error deleting draft plans: %v", err)
	}

	defer res.Close()

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the wrapped error for the offending field path and remove or retype it
  2. Change unsupported fields (chan/func) to serializable representations (string IDs, byte slices)
  3. Add json:"-" tags to internal-only fields that must not be marshaled
  4. Add a unit test marshaling a fully populated ConvoMessageDescription

Example fix

// before
type ConvoMessageDescription struct {
    Operations []Operation
    Done       chan struct{}
}
// after
type ConvoMessageDescription struct {
    Operations []Operation
    Done       chan struct{} `json:"-"`
}
Defensive patterns

Strategy: try-catch

Validate before calling

func isMarshalable(v any) error {
    _, err := json.Marshal(v)
    return err
}
// call isMarshalable(description) before StoreDescription

Try / catch

if err := StoreDescription(desc); err != nil {
    if strings.Contains(err.Error(), "unsupported type") {
        // offending field in struct; fix struct tags/types
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/ca67cb7df7139d08. Report an issue: GitHub.