{"record":{"id":"1cc2309e71b46ded","repo":"matryer/xbar","slug":"malformed-xbar-var-format-empty-select-options","errorCode":null,"errorMessage":"malformed xbar.var format (empty select options)","messagePattern":"malformed xbar\\.var format \\(empty select options\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/metadata/plugin_metadata.go","lineNumber":427,"sourceCode":"\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\n\t\tfor _, val := range v.Options {\n\t\t\tif val == v.Default {\n\t\t\t\tdefaultFound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !defaultFound {\n\t\t\treturn v, errParse{\n\t\t\t\tsrc: s,\n\t\t\t\terr: errors.New(\"malformed xbar.var format (default not in select options)\"),\n\t\t\t}\n\t\t}\n\tdefault: // invalid type\n\t\treturn v, errors.Errorf(\"unknown xbar.var type: %s\", v.Type)\n\t}","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/metadata/plugin_metadata.go#L409-L445","documentation":"Even when a '[' section exists in a select var's description, parsePluginVar requires at least one non-empty option after trimming and splitting on commas. If every entry between the brackets is blank, the select has no choices and this errParse is returned.","triggerScenarios":"parsePluginVar on a select var whose bracket section is empty or whitespace/comma-only, e.g. '<xbar.var>select(VAR_MODE): Mode. []</xbar.var>' or '[ , , ]' — strings.Split yields only empty strings which are skipped, leaving len(v.Options) == 0.","commonSituations":"Author left '[]' as a placeholder intending to fill options later; options deleted during editing leaving only separators; template-generated select with no options; copy-paste losing the option text between brackets.","solutions":["Put at least one real option inside the brackets: [fast,slow]","Remove stray commas/whitespace-only entries from the bracket list","Include the default value among the options (a later check also requires default ∈ options)","Re-run Parse to confirm the var now parses"],"exampleFix":"// before\n// <xbar.var>select(VAR_REGION): Region. []</xbar.var>\n// after\n// <xbar.var>select(VAR_REGION): Region. [us-east-1,eu-west-1]</xbar.var>","handlingStrategy":"validation","validationCode":"func bracketOptionsNonEmpty(line string) bool {\n\ti := strings.Index(line, \"[\")\n\tj := strings.Index(line, \"]\")\n\tif i < 0 || j <= i {\n\t\treturn false\n\t}\n\tinner := line[i+1 : j]\n\tfor _, o := range strings.Split(inner, \",\") {\n\t\tif strings.TrimSpace(o) != \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":"func hasPopulatedOptions(line string) bool {\n\treturn bracketOptionsNonEmpty(line)\n}","tryCatchPattern":"v, err := metadata.Parse(src)\nif err != nil {\n\tif strings.Contains(err.Error(), \"empty select options\") {\n\t\treturn fmt.Errorf(\"select var bracket list must contain at least one option: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Never ship '[]' placeholders — replace them with real options before committing","Avoid comma-only or whitespace-only bracket contents","Ensure the default value appears in the options list too","Add a test parsing every select var in your plugin set"],"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"}