googleapis/mcp-toolbox · error
conflicting source configuration: readOnly is %v, but writeM
Error message
conflicting source configuration: readOnly is %v, but writeMode is %q
What it means
Initialize cross-checks the readOnly boolean against writeMode. A writeMode of 'blocked' or 'protected' implies read-only, and 'allowed' implies writable; if the explicit readOnly flag disagrees with what writeMode implies, initialization fails with this error rather than guessing intent.
Source
Thrown at internal/sources/bigquery/bigquery.go:157
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
if r.WriteMode == "" {
r.WriteMode = WriteModeAllowed
if r.ReadOnly != nil && *r.ReadOnly {
r.WriteMode = WriteModeBlocked
}
}
if r.WriteMode != WriteModeAllowed && r.WriteMode != WriteModeBlocked && r.WriteMode != WriteModeProtected {
return nil, fmt.Errorf("invalid writeMode %q: must be one of %q, %q, or %q", r.WriteMode, WriteModeAllowed, WriteModeProtected, WriteModeBlocked)
}
if r.ReadOnly != nil {
// 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")
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Make readOnly agree with writeMode: blocked/protected => readOnly: true; allowed => readOnly: false.
- Remove the readOnly field and express intent purely via writeMode.
- Remove writeMode and express intent purely via readOnly: true (auto-maps to blocked).
Example fix
// before readOnly: true writeMode: allowed // after readOnly: true writeMode: blocked
Defensive patterns
Strategy: validation
Validate before calling
func validateReadOnlyWriteMode(readOnly *bool, writeMode string) error {
if readOnly == nil { return nil }
isRO := writeMode == "blocked" || writeMode == "protected"
if *readOnly != isRO {
return fmt.Errorf("readOnly=%v conflicts with writeMode=%q", *readOnly, writeMode)
}
return nil
} Try / catch
src, err := sourceRegistry.Initialize(ctx, cfg)
if err != nil {
if strings.Contains(err.Error(), "conflicting source configuration") {
return fmt.Errorf("align readOnly and writeMode: %w", err)
}
return err
} Prevention
- Express write intent with only ONE of readOnly or writeMode, never both.
- Document that protected/blocked are read-only modes in your config templates.
- Add a config review checklist item for these two fields.
When it happens
Trigger: Configuring both readOnly and writeMode with contradictory values, e.g. readOnly: true with writeMode: allowed, or readOnly: false with writeMode: blocked/protected.
Common situations: Merging config fragments where one sets readOnly: true and another adds writeMode: allowed; misunderstanding that protected is a read-only mode; copy-pasting examples with both fields set.
Related errors
- invalid writeMode %q: must be one of %q, %q, or %q
- invalid allowedDataset format: %q, expected 'project.dataset
- dialect invalid: must be one of "googlesql", or "postgresql"
- doc %d: unexpected non-string key in input: %v
- doc %d: invalid config format at key %q: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/c0c6416897fb22c1.
Report an issue: GitHub.