kgretzky/evilginx2 · error

edit: %v

Error message

edit: %v

What it means

Thrown by the `lures edit <id> pause <duration>` command handler in handleLures when updating the lure's PausedUntil timestamp via cfg.SetLure fails. The underlying persistence error (file write/serialization failure) is wrapped with the 'edit:' prefix. It means the pause was applied in memory but could not be saved to the lure configuration file.

Source

Thrown at core/terminal.go:879

				}
				l, err := t.cfg.GetLure(l_id)
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				s_duration := args[2]

				t_dur, err := ParseDurationString(s_duration)
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				t_now := time.Now()
				log.Info("current time: %s", t_now.Format("2006-01-02 15:04:05"))
				log.Info("unpauses at:  %s", t_now.Add(t_dur).Format("2006-01-02 15:04:05"))

				l.PausedUntil = t_now.Add(t_dur).Unix()
				err = t.cfg.SetLure(l_id, l)
				if err != nil {
					return fmt.Errorf("edit: %v", err)
				}
				return nil
			}
		case "unpause":
			if pn == 2 {
				l_id, err := strconv.Atoi(strings.TrimSpace(args[1]))
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}
				l, err := t.cfg.GetLure(l_id)
				if err != nil {
					return fmt.Errorf("pause: %v", err)
				}

				log.Info("lure for phishlet '%s' unpaused", l.Phishlet)

				l.PausedUntil = 0
				err = t.cfg.SetLure(l_id, l)

View on GitHub (pinned to 4c0988a1d9)

Solutions

  1. Check filesystem permissions on the config directory and lures file (must be writable by the process)
  2. Verify the lure id still exists with `lures get` before editing
  3. Check disk space with df -h
  4. Inspect the wrapped inner error (%v) for the exact persistence failure cause

Example fix

// before
err = t.cfg.SetLure(l_id, l)
if err != nil {
	return fmt.Errorf("edit: %v", err)
}
// after
err = t.cfg.SetLure(l_id, l)
if err != nil {
	return fmt.Errorf("edit lure %d: failed to persist pause: %w", l_id, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(cfgPath); err != nil || !writable(cfgPath) { /* abort before edit */ }

Type guard

func lureExists(id int) bool { _, err := cfg.GetLure(id); return err == nil }

Try / catch

err := t.cfg.SetLure(l_id, l)
if err != nil {
	return fmt.Errorf("edit: persist pause failed: %w", err)
}

Prevention

When it happens

Trigger: `lures edit <id> pause <dur>` when SetLure returns an error: config file unreadable, lures.yaml corrupted, disk full, or the lure was deleted concurrently between GetLure and SetLure.

Common situations: Running evilginx3 with a read-only config directory, permission changed on ~/.evilginx or the lures file, or an operator deleting the lure from another session while pausing it.

Related errors


AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05). Data as JSON: /api/errors/ae0e0e9e73211cf3. Report an issue: GitHub.