urfave/cli · error
item %q is missing separator %q
Error message
item %q is missing separator %q
What it means
For map flags (MapFlag), each value must be a key=value pair. Set splits the raw string into items (honoring the slice separator, default ','), then splits each item on the key/value separator (default '='). If an item contains no separator, it returns "item %q is missing separator %q".
Source
Thrown at flag_map_impl.go:82
}
mvc := &i.multiValueConfig
keyValueSeparator := mvc.MapFlagKeyValueSeparator
if len(keyValueSeparator) == 0 {
keyValueSeparator = defaultMapFlagKeyValueSeparator
}
tracef(
"splitting map value '%s', keyValueSeparator '%s', slice separator '%s', disable separator:%v",
value,
keyValueSeparator,
mvc.SliceFlagSeparator,
mvc.DisableSliceFlagSeparator,
)
for _, item := range flagSplitMultiValues(value, mvc.SliceFlagSeparator, mvc.DisableSliceFlagSeparator) {
key, value, ok := strings.Cut(item, keyValueSeparator)
if !ok {
return fmt.Errorf("item %q is missing separator %q", item, keyValueSeparator)
}
if err := i.value.Set(value); err != nil {
return err
}
(*i.dict)[key] = i.value.Get().(T)
}
return nil
}
// String returns a readable representation of this value (for usage defaults)
func (i *MapBase[T, C, VC]) String() string {
v := i.Value()
var t T
if reflect.TypeOf(t).Kind() == reflect.String {
return fmt.Sprintf("%v", v)
}
return fmt.Sprintf("%T{%s}", v, i.ToString(v))View on GitHub (pinned to 1a4deb4f5a)
Solutions
- Ensure every comma-separated item is in key=value form, e.g. --opts a=1,b=2.
- Quote the whole value in the shell so '=' and ',' survive: --opts "a=1,b=2".
- Check SliceFlagSeparator configuration; if the separator was changed (or DisableSliceFlagSeparator set), items must be split on the configured separator.
- Inspect the input for stray commas producing empty or malformed items and remove them.
Example fix
// before myapp --opts key1,key2=value // after myapp --opts "key1=value1,key2=value2"
Defensive patterns
Strategy: validation
Validate before calling
// shell: validate every comma-separated item contains '='
value="key1=v1,key2=v2"
IFS=',' read -ra items <<< "$value"
for it in "${items[@]}"; do
[[ "$it" == *=* ]] || { echo "bad map item (needs key=value): $it" >&2; exit 1; }
done Type guard
func validMapValue(v string, sep string) bool {
for _, item := range strings.Split(v, sep) {
if !strings.Contains(item, "=") { return false }
}
return true
} Try / catch
if err := cmd.Run(ctx, os.Args); err != nil {
if strings.Contains(err.Error(), "is missing separator") {
fmt.Fprintln(os.Stderr, "map flags need key=value pairs, e.g. --opts a=1,b=2")
os.Exit(2)
}
return err
} Prevention
- Always write map flag values as comma-separated key=value pairs.
- Quote the value in shells so ',' and '=' are preserved.
- Remember empty items (double commas) are also invalid.
- If you changed SliceFlagSeparator, update all callers to the new separator.
When it happens
Trigger: Passing a map flag value without '=' in one of the comma-separated items, e.g. `--opts foo` or `--opts a=1,b` (the item "b" has no '='), or an empty item like `--opts a=1,,b=2`.
Common situations: Users familiar with slice flags passing bare values to a map flag; shell quoting stripping the '=' or splitting items unexpectedly; copy-pasted config where the last pair lost its value (e.g. `a=1,b=` still works, but trailing `,b` does not).
Related errors
- could not parse %[1]q as %[2]T value from %[3]s for flag %[4
- could not parse %[1]q as %[2]T value from %[3]s for flag %[4
- no such flag -%s
- flag needs an argument: %s
- flag provided but not defined: -%s
AI-assisted analysis of urfave/cli@1a4deb4f5a (2026-08-31).
Data as JSON: /api/errors/bad5dfe9c69b8ae1.
Report an issue: GitHub.