m1k1o/neko · error

invalid stream selector type: %s

Error message

invalid stream selector type: %s

What it means

StreamSelectorType.UnmarshalText parses a textual stream-selection mode and only accepts the known cases (e.g., "nearest", "lower", "higher"). Any other string fails with this error. It surfaces from JSON/TOML/YAML text unmarshalling of configuration that uses StreamSelectorType fields.

Source

Thrown at server/pkg/types/capture.go:88

	case StreamSelectorTypeHigher:
		return "higher"
	default:
		return fmt.Sprintf("%d", int(s))
	}
}

func (s *StreamSelectorType) UnmarshalText(text []byte) error {
	switch strings.ToLower(string(text)) {
	case "exact", "":
		*s = StreamSelectorTypeExact
	case "nearest":
		*s = StreamSelectorTypeNearest
	case "lower":
		*s = StreamSelectorTypeLower
	case "higher":
		*s = StreamSelectorTypeHigher
	default:
		return fmt.Errorf("invalid stream selector type: %s", string(text))
	}
	return nil
}

func (s StreamSelectorType) MarshalText() ([]byte, error) {
	return []byte(s.String()), nil
}

type StreamSelector struct {
	// type of stream selector
	Type StreamSelectorType `json:"type"`
	// select stream by its ID
	ID string `json:"id"`
	// select stream by its bitrate
	Bitrate uint64 `json:"bitrate"`
}

type StreamSelectorManager interface {

View on GitHub (pinned to b0f01cedea)

Solutions

  1. Set the value to one of the accepted literals exactly as defined in StreamSelectorType.String(): "nearest", "lower", or "higher".
  2. Fix case: parsing is case-sensitive, so use lowercase ("higher", not "Higher").
  3. Check for typos/whitespace in the config value and consult capture.go for the current list of valid StreamSelectorType constants.

Example fix

// before (config.json)
"streamSelector": "Highest"
// after
"streamSelector": "higher"
Defensive patterns

Strategy: validation

Validate before calling

valid := map[string]bool{"nearest": true, "lower": true, "higher": true}
if !valid[strings.ToLower(strings.TrimSpace(cfg.StreamSelector))] {
    return fmt.Errorf("streamSelector must be nearest|lower|higher")
}

Type guard

func isValidStreamSelector(s string) bool {
    var t types.StreamSelectorType
    return t.UnmarshalText([]byte(s)) == nil
}

Try / catch

var sel types.StreamSelectorType
if err := json.Unmarshal(raw, &sel); err != nil {
    if strings.Contains(err.Error(), "invalid stream selector type") {
        sel = types.StreamSelectorTypeNearest // safe default
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Unmarshalling a config file or API payload (encoding/json TextUnmarshaler, yaml/toml wrappers) into a StreamSelectorType field where the text is not one of the accepted constants — e.g., "auto", "lowest", "Highest", or an empty string.

Common situations: Typo in config ("higer", "low"); case mismatch since parsing is case-sensitive ("Higher" fails); upgrading from an older config that used a removed alias; hand-writing YAML/JSON values without checking StreamSelectorType.String() output.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01). Data as JSON: /api/errors/d6801b2abb03376f. Report an issue: GitHub.