googleapis/mcp-toolbox · error
writeMode 'protected' cannot be used with useClientOAuth ena
Error message
writeMode 'protected' cannot be used with useClientOAuth enabled
What it means
The 'protected' write mode preserves session temporary datasets across tool invocations, which requires a single long-lived authenticated client. With useClientOAuth enabled, a fresh session/client is created per invocation, so temporary dataset state cannot survive; Initialize rejects this combination outright.
Source
Thrown at internal/sources/bigquery/bigquery.go:170
// A writeMode is considered a read-only mode if it is Blocked or Protected.
isReadOnlyMode := (r.WriteMode == WriteModeBlocked || r.WriteMode == WriteModeProtected)
// The declared readOnly boolean must match the writeMode's behavior.
if *r.ReadOnly != isReadOnlyMode {
return nil, fmt.Errorf("conflicting source configuration: readOnly is %v, but writeMode is %q", *r.ReadOnly, r.WriteMode)
}
}
if r.MaxQueryResultRows == 0 {
r.MaxQueryResultRows = 50
}
if r.WriteMode == WriteModeProtected && strings.ToLower(r.UseClientOAuth) != "false" && r.UseClientOAuth != "" {
// The protected mode only allows write operations to the session's temporary datasets.
// when using client OAuth, a new session is created every
// time a BigQuery tool is invoked. Therefore, no session data can
// be preserved as needed by the protected mode.
return nil, fmt.Errorf("writeMode 'protected' cannot be used with useClientOAuth enabled")
}
if strings.ToLower(r.UseClientOAuth) != "false" && r.UseClientOAuth != "" && r.ImpersonateServiceAccount != "" {
return nil, fmt.Errorf("useClientOAuth cannot be used with impersonateServiceAccount")
}
endpoint := NormalizeEndpoint(r.APIEndpoint)
var client *bigqueryapi.Client
var restService *bigqueryrestapi.Service
var tokenSource oauth2.TokenSource
var clientCreator BigqueryClientCreator
var err error
s := &Source{
Config: r,
Client: client,
RestService: restService,View on GitHub (pinned to 8cc6e09de2)
Solutions
- Change writeMode to 'allowed' or 'blocked' if client OAuth must stay enabled.
- Set useClientOAuth: "false" if protected mode is required and service-account auth is acceptable.
- If per-session temp tables are needed with client OAuth, restructure the workflow to not depend on cross-invocation session state.
Example fix
// before useClientOAuth: "true" writeMode: protected // after useClientOAuth: "false" writeMode: protected
Defensive patterns
Strategy: validation
Validate before calling
func validateProtectedOAuth(writeMode, useClientOAuth string) error {
clientOAuth := useClientOAuth != "" && strings.ToLower(useClientOAuth) != "false"
if writeMode == "protected" && clientOAuth {
return fmt.Errorf("writeMode 'protected' is incompatible with useClientOAuth")
}
return nil
} Try / catch
src, err := sourceRegistry.Initialize(ctx, cfg)
if err != nil {
if strings.Contains(err.Error(), "cannot be used with useClientOAuth") {
return fmt.Errorf("choose either client OAuth or protected mode: %w", err)
}
return err
} Prevention
- Remember useClientOAuth is enabled unless explicitly set to "false".
- If sessions/temp datasets must persist, keep client OAuth off.
- Test source initialization in CI with the production config.
When it happens
Trigger: BigQuery source config with writeMode: protected AND useClientOAuth set to anything other than "false" or empty (i.e. enabled, since it defaults to enabled unless explicitly "false").
Common situations: Enabling per-user client OAuth for multi-tenant setups while keeping protected mode from an earlier config; forgetting that useClientOAuth is on by default when omitted.
Related errors
- useClientOAuth cannot be used with impersonateServiceAccount
- error constructing client creator: %w
- authService %q declared more than once
- %s is not a valid type of auth service
- `authRequired` and `useClientOAuth` are mutually exclusive.
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/81ef26b8bfa3416f.
Report an issue: GitHub.