kubernetes/kops · error

cannot parse flag spec: %q

Error message

cannot parse flag spec: %q

What it means

flagbuilder parses struct tags of the form `flag:"name,option,..."`. The only option currently recognized after the flag name is `repeat`; any other comma-separated token makes the walker abort with this error. It is a programmer error in the tag definition, not a runtime/user issue.

Source

Thrown at pkg/flagbuilder/build_flags.go:79

		}
		if tag == "-" {
			klog.V(4).Infof("skipping field with %q flag tag: %s", tag, path)
			return reflectutils.SkipReflection
		}

		// If we specify the repeat option, we will repeat the flag rather than joining it with commas
		repeatFlag := false

		tokens := strings.Split(tag, ",")
		if len(tokens) > 1 {
			for i, t := range tokens {
				if i == 0 {
					continue
				}
				if t == "repeat" {
					repeatFlag = true
				} else {
					return fmt.Errorf("cannot parse flag spec: %q", tag)
				}
			}
		}
		flagName := tokens[0]

		// If the "unset" value is not empty string, by setting this tag we avoid passing spurious flag values
		flagEmpty := field.Tag.Get("flag-empty")

		flagIncludeEmpty, _ := strconv.ParseBool(field.Tag.Get("flag-include-empty"))

		// We do have to do this, even though the recursive walk will do it for us
		// because when we descend we won't have `field` set
		if val.Kind() == reflect.Ptr && reflect.TypeOf(val.Interface()).String() != "*string" {
			if val.IsNil() {
				return nil
			}
			val = val.Elem()
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Fix the struct tag to use only `flag:"name"` or `flag:"name,repeat"`
  2. Remove the extra tokens from the tag if the option was not intended
  3. If a new option is genuinely needed, extend the parser at build_flags.go:76-80 to recognize it

Example fix

// before
MaxPods int32 `flag:"max-pods,repeate"`
// after
MaxPods int32 `flag:"max-pods"`
Defensive patterns

Strategy: validation

Validate before calling

// Before building flags, sanity-check every flag tag in your option structs
t := reflect.TypeOf(MyOptions{})
for i := 0; i < t.NumField(); i++ {
	tag := t.Field(i).Tag.Get("flag")
	for _, tok := range strings.Split(tag, ",")[1:] {
		if tok != "repeat" {
			panic(fmt.Sprintf("invalid flag tag %q on field %s", tag, t.Field(i).Name))
		}
	}
}

Prevention

When it happens

Trigger: A struct field has a `flag` tag containing extra tokens after the flag name that are not exactly `repeat`, e.g. `flag:"my-flag,repeated"` or `flag:"my-flag,foo"`; BuildFlags/BuildFlagsList then hits the walker at build_flags.go:79.

Common situations: Typos in the tag (writing 'repeats' or 'repeat-all' instead of 'repeat'), copying tag conventions from other libraries, or adding new tag options without extending the parser.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/af0288ccfa9298ca. Report an issue: GitHub.