plandex-ai/plandex · error

error scanning deleted draft plan id: %v

Error message

error scanning deleted draft plan id: %v

What it means

While iterating rows returned by the draft-plan DELETE, res.Scan(&id) failed to copy a RETURNING id value into a string. With DELETE ... RETURNING id this normally only fails on driver/protocol errors, NULL ids, or rows.Next/Scan misuse.

Source

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

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

	// get ids
	var ids []string

	for res.Next() {
		var id string
		err := res.Scan(&id)
		if err != nil {
			return fmt.Errorf("error scanning deleted draft plan id: %v", err)
		}
		ids = append(ids, id)
	}

	errCh := make(chan error, len(ids))
	for _, planId := range ids {
		go func(planId string) {
			defer func() {
				if r := recover(); r != nil {
					log.Printf("panic in DeleteDraftPlans: %v\n%s", r, debug.Stack())
					errCh <- fmt.Errorf("panic in DeleteDraftPlans: %v\n%s", r, debug.Stack())
					runtime.Goexit() // don't allow outer function to continue and double-send to channel
				}
			}()
			errCh <- DeletePlanDir(orgId, planId)
		}(planId)
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Confirm RETURNING list matches the Scan arguments exactly
  2. Check the wrapped driver error for connection/protocol issues
  3. Ensure the id column is NOT NULL primary key
  4. Use errors.Is/As with pq errors for precise diagnosis

Example fix

// before
var id string
err := res.Scan(&id)
if err != nil {
    return fmt.Errorf("error scanning deleted draft plan id: %v", err)
}
// after
var id string
if err := res.Scan(&id); err != nil {
    return fmt.Errorf("error scanning deleted draft plan id: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify RETURNING columns match Scan args
// query: DELETE FROM plans WHERE ... RETURNING id;  -> Scan(&id) only

Try / catch

if err := DeleteDraftPlans(orgId, projectId, userId); err != nil {
    if errors.Is(err, driver.ErrBadConn) || errors.Is(err, io.EOF) {
        // connection lost mid-result-set; retry the operation
    }
    return err
}

Prevention

When it happens

Trigger: res.Scan(&id) errors during the rows loop: driver connection lost mid-result-set, id column NULL, or the query was changed to return extra columns that no longer match Scan args.

Common situations: Connection reset while streaming large result sets; someone added columns to RETURNING without updating Scan; NULL id values from schema changes allowing NULL primary keys.

Related errors


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