{"record":{"id":"1876f163148ab7ea","repo":"matryer/xbar","slug":"malformed-xbar-var-format-missing-select-options","errorCode":null,"errorMessage":"malformed xbar.var format (missing select options)","messagePattern":"malformed xbar\\.var format \\(missing select options\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/metadata/plugin_metadata.go","lineNumber":412,"sourceCode":"\t\tv.Name = nameSegs[0]\n\t\tv.Default = strings.Trim(nameSegs[1], `\"'`)\n\t}\n\tv.Label = v.Name\n\tif strings.HasPrefix(v.Name, \"VAR_\") {\n\t\tv.Label = strings.ToLower(strings.TrimPrefix(v.Name, \"VAR_\"))\n\t\tv.Label = strings.ToUpper(v.Label[0:1]) + v.Label[1:]\n\t\tv.Label = strings.ReplaceAll(v.Label, \"_\", \" \")\n\t}\n\tswitch v.Type {\n\tcase \"string\", \"number\", \"boolean\":\n\t\t// valid types - but no work to do\n\tcase \"select\":\n\t\t// extract options from description\n\t\tlistSegs := strings.Split(v.Desc, `[`)\n\t\tif len(listSegs) < 2 {\n\t\t\treturn v, errParse{\n\t\t\t\tsrc: s,\n\t\t\t\terr: errors.New(\"malformed xbar.var format (missing select options)\"),\n\t\t\t}\n\t\t}\n\t\tv.Desc = strings.TrimSpace(listSegs[0])\n\t\toptionsStr := strings.TrimSuffix(listSegs[1], `]`)\n\t\tfor _, option := range strings.Split(optionsStr, \",\") {\n\t\t\tcleanStr := strings.TrimSpace(option)\n\t\t\tif cleanStr == \"\" {\n\t\t\t\tcontinue // skip empty lines\n\t\t\t}\n\t\t\tv.Options = append(v.Options, cleanStr)\n\t\t}\n\t\tif len(v.Options) == 0 {\n\t\t\treturn v, errParse{\n\t\t\t\tsrc: s,\n\t\t\t\terr: errors.New(\"malformed xbar.var format (empty select options)\"),\n\t\t\t}\n\t\t}\n\t\tdefaultFound := false","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/metadata/plugin_metadata.go#L394-L430","documentation":"For xbar.var lines of type 'select', the allowed options must be embedded in the description inside square brackets, e.g. string(VAR_MODE): Mode [fast,slow]. If the description contains no '[' so no options list can be extracted, parsePluginVar returns this errParse — a select variable without options is unusable for the menu UI.","triggerScenarios":"parsePluginVar (via Parse) on a line like '<xbar.var>select(VAR_MODE): Choose mode.</xbar.var>' where v.Desc contains no '[' — the [option1,option2] list was omitted, placed outside the description, or the line was mistyped as another type after editing.","commonSituations":"Authors writing select vars like plain string vars and forgetting the [a,b,c] options; options list removed during editing; trailing period or newline after the brackets placed before them; converting a string var to select without adding options.","solutions":["Append the options list to the description: <xbar.var>select(VAR_MODE): Mode. [fast,slow]</xbar.var>","Ensure the '[' appears in the same description text after the colon","Keep at least one non-empty option inside the brackets, comma-separated","Re-run Parse and check errParse.src for the offending line"],"exampleFix":"// before\n// <xbar.var>select(VAR_MODE): Choose the mode.</xbar.var>\n// after\n// <xbar.var>select(VAR_MODE): Choose the mode. [fast,slow]</xbar.var>","handlingStrategy":"validation","validationCode":"var selectRe = regexp.MustCompile(`(?s)<xbar\\.var>select\\((.+)\\):\\s*(.+?)\\s*\\[.+\\]\\s*</xbar\\.var>`)\n\nfunc selectHasOptions(line string) bool {\n\treturn selectRe.MatchString(strings.TrimSpace(line))\n}","typeGuard":"func isSelectWithOptions(line string) bool {\n\tm := selectRe.FindStringSubmatch(line)\n\treturn m != nil && strings.Contains(m[2], \"[\")\n}","tryCatchPattern":"v, err := metadata.Parse(src)\nif err != nil {\n\tif strings.Contains(err.Error(), \"missing select options\") {\n\t\treturn fmt.Errorf(\"select vars need a [option1,option2] list in the description: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Every select var's description must end with [opt1,opt2,...] inside the description text","Never write select vars like string vars","Put the bracket list after the description sentence, before </xbar.var>","Lint select lines for the bracket section in CI"],"tags":["metadata","parsing","xbar-var","select","go"],"backgroundTag":"malformed-var-declaration","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}