matryer/xbar · error

malformed xbar.var format (empty select options)

Error message

malformed xbar.var format (empty select options)

What it means

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.

Source

Thrown at pkg/metadata/plugin_metadata.go:427

		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
		for _, val := range v.Options {
			if val == v.Default {
				defaultFound = true
				break
			}
		}
		if !defaultFound {
			return v, errParse{
				src: s,
				err: errors.New("malformed xbar.var format (default not in select options)"),
			}
		}
	default: // invalid type
		return v, errors.Errorf("unknown xbar.var type: %s", v.Type)
	}

View on GitHub (pinned to d624239058)

Solutions

  1. Put at least one real option inside the brackets: [fast,slow]
  2. Remove stray commas/whitespace-only entries from the bracket list
  3. Include the default value among the options (a later check also requires default ∈ options)
  4. Re-run Parse to confirm the var now parses

Example fix

// before
// <xbar.var>select(VAR_REGION): Region. []</xbar.var>
// after
// <xbar.var>select(VAR_REGION): Region. [us-east-1,eu-west-1]</xbar.var>
Defensive patterns

Strategy: validation

Validate before calling

func bracketOptionsNonEmpty(line string) bool {
	i := strings.Index(line, "[")
	j := strings.Index(line, "]")
	if i < 0 || j <= i {
		return false
	}
	inner := line[i+1 : j]
	for _, o := range strings.Split(inner, ",") {
		if strings.TrimSpace(o) != "" {
			return true
		}
	}
	return false
}

Type guard

func hasPopulatedOptions(line string) bool {
	return bracketOptionsNonEmpty(line)
}

Try / catch

v, err := metadata.Parse(src)
if err != nil {
	if strings.Contains(err.Error(), "empty select options") {
		return fmt.Errorf("select var bracket list must contain at least one option: %w", err)
	}
	return err
}

Prevention

When it happens

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

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

Understand the failure class

Related errors


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