matryer/xbar · error

malformed xbar.var format (missing select options)

Error message

malformed xbar.var format (missing select options)

What it means

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.

Source

Thrown at pkg/metadata/plugin_metadata.go:412

		v.Name = nameSegs[0]
		v.Default = strings.Trim(nameSegs[1], `"'`)
	}
	v.Label = v.Name
	if strings.HasPrefix(v.Name, "VAR_") {
		v.Label = strings.ToLower(strings.TrimPrefix(v.Name, "VAR_"))
		v.Label = strings.ToUpper(v.Label[0:1]) + v.Label[1:]
		v.Label = strings.ReplaceAll(v.Label, "_", " ")
	}
	switch v.Type {
	case "string", "number", "boolean":
		// valid types - but no work to do
	case "select":
		// extract options from description
		listSegs := strings.Split(v.Desc, `[`)
		if len(listSegs) < 2 {
			return v, errParse{
				src: s,
				err: errors.New("malformed xbar.var format (missing select options)"),
			}
		}
		v.Desc = strings.TrimSpace(listSegs[0])
		optionsStr := strings.TrimSuffix(listSegs[1], `]`)
		for _, option := range strings.Split(optionsStr, ",") {
			cleanStr := strings.TrimSpace(option)
			if cleanStr == "" {
				continue // skip empty lines
			}
			v.Options = append(v.Options, cleanStr)
		}
		if len(v.Options) == 0 {
			return v, errParse{
				src: s,
				err: errors.New("malformed xbar.var format (empty select options)"),
			}
		}
		defaultFound := false

View on GitHub (pinned to d624239058)

Solutions

  1. Append the options list to the description: <xbar.var>select(VAR_MODE): Mode. [fast,slow]</xbar.var>
  2. Ensure the '[' appears in the same description text after the colon
  3. Keep at least one non-empty option inside the brackets, comma-separated
  4. Re-run Parse and check errParse.src for the offending line

Example fix

// before
// <xbar.var>select(VAR_MODE): Choose the mode.</xbar.var>
// after
// <xbar.var>select(VAR_MODE): Choose the mode. [fast,slow]</xbar.var>
Defensive patterns

Strategy: validation

Validate before calling

var selectRe = regexp.MustCompile(`(?s)<xbar\.var>select\((.+)\):\s*(.+?)\s*\[.+\]\s*</xbar\.var>`)

func selectHasOptions(line string) bool {
	return selectRe.MatchString(strings.TrimSpace(line))
}

Type guard

func isSelectWithOptions(line string) bool {
	m := selectRe.FindStringSubmatch(line)
	return m != nil && strings.Contains(m[2], "[")
}

Try / catch

v, err := metadata.Parse(src)
if err != nil {
	if strings.Contains(err.Error(), "missing select options") {
		return fmt.Errorf("select vars need a [option1,option2] list in the description: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02). Data as JSON: /api/errors/1876f163148ab7ea. Report an issue: GitHub.