JuliusBrussee/caveman · error
duplicate
Error message
duplicate %s
What it means
parseStatsReportOptions (proxy/cmd/caveman-proxy/stats.go:24) parses the flags for the stats report command and enforces that each option appears at most once, tracking them in a seen map. Repeating any recognized or unrecognized option — even with the same value — is rejected as 'duplicate <arg>'. This keeps the report configuration unambiguous.
Solutions
- Remove the duplicated flag, keeping a single occurrence with the desired value
- Audit wrapper scripts/aliases that may inject the same flag the user also supplies
- Remember the rule applies to every option string, including boolean --report/--json
Example fix
// before caveman-proxy stats --days 7 --days 30 --report // after caveman-proxy stats --days 30 --report
Defensive patterns
Strategy: validation
Validate before calling
function assertNoDuplicateFlags(args) {
const seen = new Set();
for (const a of args.filter(x => x.startsWith("--"))) {
if (seen.has(a)) throw new Error(`duplicate flag ${a}`);
seen.add(a);
}
} Prevention
- Build command lines from arrays/dicts keyed by flag name so duplicates are impossible
- Audit wrapper scripts that append default flags
- Review the final argv before invoking stats in shell scripts
When it happens
Trigger: Running the stats command with the same flag twice, e.g. 'stats --days 7 --days 30' or '--report --report'. The second occurrence hits seen[arg]==true and returns this error.
Common situations: Shell scripts appending flags conditionally and repeating one; copy-pasting a command line where a flag was already present; aliases or wrappers that inject default flags the user also typed.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- requires a value
- unknown stats report option
- requires a value
- --days must be an integer from 0 to 3660
- duplicate
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/f592d1f438ff811e.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/cmd/caveman-proxy/stats.go:24
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/JuliusBrussee/caveman/proxy/internal/store"
)
// The richer report is explicitly selected. Existing stats --json callers
// (telemetry and session footers) keep their original schema and behavior.
func parseStatsReportOptions(args []string) (store.StatsReportOptions, bool, string, error) {
opts := store.StatsReportOptions{Days: 30, Now: time.Now()}
writeReport, out := false, ""
seen := map[string]bool{}
for i := 0; i < len(args); i++ {
arg := args[i]
if seen[arg] {
return opts, false, "", fmt.Errorf("duplicate %s", arg)
}
seen[arg] = true
switch arg {
case "--report", "--json":
case "--write-report":
writeReport = true
case "--days", "--provider", "--model", "--agent", "--auth", "--out":
i++
if i >= len(args) || args[i] == "" || strings.HasPrefix(args[i], "--") || strings.ContainsAny(args[i], "\x00\r\n") {
return opts, false, "", fmt.Errorf("%s requires a value", arg)
}
value := args[i]
switch arg {
case "--days":
days, err := strconv.Atoi(value)
if err != nil || days < 0 || days > 3660 {
return opts, false, "", fmt.Errorf("--days must be an integer from 0 to 3660")
}View on GitHub (pinned to 3ee70a1026)