googleapis/mcp-toolbox · error
invalid writeMode %q: must be one of %q, %q, or %q
Error message
invalid writeMode %q: must be one of %q, %q, or %q
What it means
The BigQuery source validates the writeMode config field during Initialize. Only 'allowed', 'blocked', or 'protected' are accepted; any other string fails this check right after the readOnly-defaulting logic. This prevents silent typos that would otherwise make write behavior undefined.
Source
Thrown at internal/sources/bigquery/bigquery.go:148
}
return fmt.Errorf("cannot unmarshal %T into StringOrStringSlice", v)
}
func (r Config) SourceConfigType() string {
// Returns BigQuery source type
return SourceType
}
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.View on GitHub (pinned to 8cc6e09de2)
Solutions
- Set writeMode to one of: allowed, blocked, protected (lowercase, exact).
- Remove writeMode entirely to get the default behavior, optionally using readOnly instead.
- If intent is read-only, set readOnly: true and drop writeMode; it will be set to blocked automatically.
Example fix
// before writeMode: readonly // after writeMode: protected
Defensive patterns
Strategy: validation
Validate before calling
var validWriteModes = map[string]bool{"allowed": true, "blocked": true, "protected": true}
func validateWriteMode(mode string) error {
if !validWriteModes[mode] {
return fmt.Errorf("writeMode %q must be allowed|blocked|protected", mode)
}
return nil
} Type guard
func isValidWriteMode(s string) bool {
return s == "allowed" || s == "blocked" || s == "protected"
} Try / catch
src, err := sourceRegistry.Initialize(ctx, cfg)
if err != nil {
if strings.Contains(err.Error(), "invalid writeMode") {
return fmt.Errorf("fix writeMode in config: %w", err)
}
return err
} Prevention
- Copy writeMode values only from official docs (allowed/blocked/protected, lowercase).
- Prefer the readOnly boolean when only read-only behavior is needed.
- Validate config values in CI before shipping tools.yaml.
When it happens
Trigger: Setting writeMode in the BigQuery source config to any value other than exactly 'allowed', 'blocked', or 'protected' (note: a readOnly: true config auto-sets blocked, so this fires only when writeMode is explicitly invalid).
Common situations: Typos like 'write', 'read-write', 'Allow' (case-sensitive), or copying a writeMode value from a different source (e.g. Postgres) that uses different mode names.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- conflicting source configuration: readOnly is %v, but writeM
- 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/f7323d5f5a95b0cb.
Report an issue: GitHub.