{"record":{"id":"c8b2aca5bdcdb639","repo":"AdguardTeam/AdGuardHome","slug":"parsing-arg-at-index-d-w","errorCode":null,"errorMessage":"parsing arg at index %d: %w","messagePattern":"parsing arg at index (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/home/options.go","lineNumber":397,"sourceCode":"\t}\n\n\t_, err = fmt.Print(b)\n\tif err != nil {\n\t\t// Exit immediately, since not being able to print out a help message\n\t\t// essentially means that the I/O is very broken at the moment.\n\t\texitWithError()\n\t}\n}\n\n// parseCmdOpts parses the command-line arguments into options and effects.\nfunc parseCmdOpts(cmdName string, args []string) (o options, eff effect, err error) {\n\tnext, stop := iter.Pull2(slices.All(args))\n\tdefer stop()\n\n\tfor i, arg, ok := next(); ok; i, arg, ok = next() {\n\t\to, eff, err = parseArg(cmdName, next, o, eff, arg)\n\t\tif err != nil {\n\t\t\treturn o, eff, fmt.Errorf(\"parsing arg at index %d: %w\", i, err)\n\t\t}\n\t}\n\n\treturn o, eff, nil\n}\n\n// parseArg parses command-line argument into options and effects.  next and\n// eff must not be nil.\nfunc parseArg(\n\tcmdName string,\n\tnext func() (int, string, bool),\n\to options,\n\teff effect,\n\targ string,\n) (newOpt options, newEff effect, err error) {\n\topt, found := findMatchingOpt(arg)\n\tif !found {\n\t\treturn o, eff, fmt.Errorf(\"unknown option %s\", arg)","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/home/options.go#L379-L415","documentation":"parseCmdOpts wraps any failure encountered while parsing a single command-line argument, annotating it with the argument's index. The inner error is the real cause — usually 'unknown option', 'got X without argument', or a value parse failure.","triggerScenarios":"Passing any malformed flag to the AdGuard Home binary (misspelled long option, option requiring a value at the end of argv, or bad numeric value); loadCmdLineOpts propagates it to Main which prints usage and exits.","commonSituations":"Typos like --verbose-extra, using flags from a different version (removed/renamed options), or omitting the value for --config / --workdir at the end of the command.","solutions":["Read the wrapped inner error and the index — argv[index] is the offending token","Run ./AdGuardHome --help to list valid options for your version","Fix or remove the flagged argument and rerun"],"exampleFix":"# before\n./AdGuardHome --workdir\n\n# after\n./AdGuardHome --workdir /var/lib/adguardhome","handlingStrategy":"try-catch","validationCode":"// Pre-screen argv before exec: run ./AdGuardHome --help parse or lint flags in scripts","typeGuard":null,"tryCatchPattern":"if err := loadCmdLineOpts(args); err != nil {\n    fmt.Fprintf(os.Stderr, \"bad args: %v (index points at the token)\", err)\n    os.Exit(2)\n}","preventionTips":["Log the full argv when wrapping the binary in scripts","Pin documentation to your binary version"],"tags":["go","cli","argument-parsing","usage"],"backgroundTag":"invalid-cli-argument","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}