router-for-me/CLIProxyAPI · error

plugin store auth missing %s

Error message

plugin store auth missing %s

What it means

envValueRequired was called with an empty env-var name for a required field (the %s names the field, e.g. token-env/username-env). internal/pluginstore/auth.go resolves secrets from the environment by name; a blank name means the auth rule is structurally incomplete — typically a bearer rule with no token-env or a basic rule missing username-env/password-env.

Source

Thrown at internal/pluginstore/auth.go:464

	return strings.HasPrefix(requestPath, rulePath+"/")
}

func authAppliesTo(item AuthConfig, kind string) bool {
	if len(item.ApplyTo) == 0 {
		return true
	}
	for _, value := range item.ApplyTo {
		if strings.EqualFold(strings.TrimSpace(value), kind) {
			return true
		}
	}
	return false
}

func envValueRequired(envName string, field string) (string, error) {
	envName = strings.TrimSpace(envName)
	if envName == "" {
		return "", fmt.Errorf("plugin store auth missing %s", field)
	}
	value := strings.TrimSpace(os.Getenv(envName))
	if value == "" {
		return "", fmt.Errorf("plugin store auth env %s is empty", envName)
	}
	return value, nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Add the missing env field for the declared type: bearer/github-token -> token-env; basic -> username-env + password-env; header -> header-value-env (+ header-name)
  2. Or set type: none if the store needs no auth
  3. Validate the full auth rule against config.example.yaml for its type

Example fix

# before
- match: https://plugins.example.com
  type: bearer

# after
- match: https://plugins.example.com
  type: bearer
  token-env: PLUGIN_TOKEN
Defensive patterns

Strategy: validation

Validate before calling

func ruleEnvFieldsComplete(r AuthConfig) error {
    switch strings.ToLower(strings.TrimSpace(r.Type)) {
    case "", "none":
        return nil
    case "bearer", "github-token":
        if strings.TrimSpace(r.TokenEnv) == "" { return fmt.Errorf("bearer rule missing token-env") }
    case "basic":
        if strings.TrimSpace(r.UsernameEnv) == "" || strings.TrimSpace(r.PasswordEnv) == "" { return fmt.Errorf("basic rule missing username-env/password-env") }
    case "header":
        if strings.TrimSpace(r.HeaderValueEnv) == "" { return fmt.Errorf("header rule missing header-value-env") }
    }
    return nil
}

Prevention

When it happens

Trigger: An auth rule declares type: bearer (or basic/header) but the corresponding *-env field is absent or empty in config, and the rule matches a store request so resolution is attempted.

Common situations: Truncated YAML block (field deleted during edit); type changed to bearer without adding token-env; JSON management payload omits the key; indentation puts the env field under a different mapping.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/aef162fb8e74e167. Report an issue: GitHub.