plandex-ai/plandex · error

unsupported data type: %T

Error message

unsupported data type: %T

What it means

PlanConfig's Scan method only accepts []byte and string (with empty string mapping to DefaultPlanConfig) and returns this error for any other driver.Value, most importantly nil for NULL columns. It indicates the plan config column value isn't JSON text the scanner can unmarshal.

Source

Thrown at app/shared/plan_config.go:120

	if src == nil {
		*p = DefaultPlanConfig
		return nil
	}
	switch s := src.(type) {
	case []byte:
		if len(s) == 0 {
			*p = DefaultPlanConfig
			return nil
		}
		return json.Unmarshal(s, p)
	case string:
		if s == "" {
			*p = DefaultPlanConfig
			return nil
		}
		return json.Unmarshal([]byte(s), p)
	default:
		return fmt.Errorf("unsupported data type: %T", src)
	}
}

func (p PlanConfig) Value() (driver.Value, error) {
	return json.Marshal(p)
}

func (p *PlanConfig) SetAutoMode(mode AutoModeType) {
	p.AutoMode = mode

	switch p.AutoMode {
	case AutoModeFull:
		p.AutoContinue = true
		p.AutoBuild = true
		p.AutoUpdateContext = true
		p.AutoLoadContext = true
		p.SmartContext = true
		p.AutoApply = true

View on GitHub (pinned to e2d772072e)

Solutions

  1. COALESCE(plan_config, '{}'::jsonb) in queries to avoid NULL reaching Scan.
  2. Add a nil case to Scan that assigns DefaultPlanConfig.
  3. Ensure the column is JSONB/TEXT with a NOT NULL DEFAULT '{}' constraint.
  4. Verify driver/ORM version behavior for JSON column decoding.

Example fix

// before
default:
    return fmt.Errorf("unsupported data type: %T", src)
// after
case nil:
    *p = DefaultPlanConfig
    return nil
default:
    return fmt.Errorf("unsupported data type: %T", src)
Defensive patterns

Strategy: type-guard

Validate before calling

var pc PlanConfig
err := db.QueryRow("SELECT COALESCE(plan_config, '{}'::jsonb) FROM plans WHERE id=$1", planId).Scan(&pc)

Type guard

func scanableJSONValue(src any) bool {
    switch src.(type) {
    case []byte, string:
        return true
    default:
        return false
    }
}

Try / catch

var pc PlanConfig
if err := rows.Scan(&pc); err != nil {
    if strings.Contains(err.Error(), "unsupported data type") {
        pc = shared.DefaultPlanConfig // fall back to defaults
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Scanning a NULL plan_config column; a driver/ORM delivering the column as a non-[]byte/string type; column type changed away from JSONB/TEXT.

Common situations: Legacy plans with NULL config columns; migrations that dropped defaults; switching drivers (e.g. pgx stdlib vs lib/pq differences in JSON decoding); raw SQL joins producing unexpected column types.

Related errors


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