googleapis/mcp-toolbox · error

parameter cannot have both 'secure' set to true and…

Error message

parameter %q cannot have both 'secure' set to true and 'authServices' specified

What it means

validateParameter enforces that a parameter cannot simultaneously be secure (value injected from server-side secure storage) and declare authServices (value sourced from client authentication credentials). Both mechanisms control how the value is obtained, so they are mutually exclusive; the config is rejected at load/parse time before any invocation.

Solutions

  1. Remove one of the two fields: drop secure:true if the value should come from auth services, or remove authServices if it should come from secure storage.
  2. Decide a single sourcing model per parameter and keep only the matching field.
  3. Re-run the toolbox after editing so config validation confirms the parameter loads.
  4. Check merge/config-layering tooling that may be re-adding the removed field.

Example fix

# before
- name: access_token
  type: string
  secure: true
  authServices:
    - kind: google

# after (auth-service sourced)
- name: access_token
  type: string
  authServices:
    - kind: google
Defensive patterns

Strategy: validation

Validate before calling

if p.GetSecure() && len(p.GetAuthServices()) > 0 {
    return fmt.Errorf("parameter %q: choose either secure or authServices, not both", p.GetName())
}

Try / catch

if err := toolbox.Start(ctx); err != nil {
    if strings.Contains(err.Error(), "cannot have both 'secure'") {
        // fix the tools YAML: remove one sourcing mechanism, then reload
    }
    return err
}

Prevention

When it happens

Trigger: Declaring a tool parameter with secure: true and a non-empty authServices list in the tools YAML — e.g. merging config fragments where one added secure:true and another added authServices. Fired by ProcessParameters or parseParamFromDelayedUnmarshaler during config load.

Common situations: Copying an authServices example onto an existing secure parameter; merging tool config files with overlapping definitions; porting a parameter between tools while keeping both fields; misunderstanding which sourcing mechanism to use.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/b2562a10ffa9fbef. Report an issue: GitHub.

Appendix: source

Thrown at internal/util/parameters/parameters.go:334

		if err := validateParameter(p); err != nil {
			return nil, nil, err
		}
	}

	// create Toolbox manifest
	paramManifest := allParameters.Manifest()
	if paramManifest == nil {
		paramManifest = make([]ParameterManifest, 0)
	}

	return allParameters, paramManifest, nil
}

// validateParameter validates that parameter configuration adheres to system constraints.
func validateParameter(p Parameter) error {
	if p.GetSecure() {
		if len(p.GetAuthServices()) > 0 {
			return fmt.Errorf("parameter %q cannot have both 'secure' set to true and 'authServices' specified", p.GetName())
		}
		if p.GetDefault() != nil {
			return fmt.Errorf("parameter %q cannot have both 'secure' set to true and 'default' specified", p.GetName())
		}
		if !p.GetRequired() {
			return fmt.Errorf("parameter %q cannot have both 'secure' set to true and 'required' set to false", p.GetName())
		}
	}
	return nil
}

type Parameter interface {
	// Note: It's typically not idiomatic to include "Get" in the function name,
	// but this is done to differentiate it from the fields in CommonParameter.
	GetName() string
	GetDesc() string
	GetType() string
	GetDefault() any

View on GitHub (pinned to 8cc6e09de2)