{"record":{"id":"f7323d5f5a95b0cb","repo":"googleapis/mcp-toolbox","slug":"invalid-writemode-q-must-be-one-of-q-q-or-q","errorCode":null,"errorMessage":"invalid writeMode %q: must be one of %q, %q, or %q","messagePattern":"invalid writeMode %q: must be one of %q, %q, or %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/bigquery/bigquery.go","lineNumber":148,"sourceCode":"\t}\n\treturn fmt.Errorf(\"cannot unmarshal %T into StringOrStringSlice\", v)\n}\n\nfunc (r Config) SourceConfigType() string {\n\t// Returns BigQuery source type\n\treturn SourceType\n}\n\nfunc (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {\n\tif r.WriteMode == \"\" {\n\t\tr.WriteMode = WriteModeAllowed\n\t\tif r.ReadOnly != nil && *r.ReadOnly {\n\t\t\tr.WriteMode = WriteModeBlocked\n\t\t}\n\t}\n\n\tif r.WriteMode != WriteModeAllowed && r.WriteMode != WriteModeBlocked && r.WriteMode != WriteModeProtected {\n\t\treturn nil, fmt.Errorf(\"invalid writeMode %q: must be one of %q, %q, or %q\", r.WriteMode, WriteModeAllowed, WriteModeProtected, WriteModeBlocked)\n\t}\n\n\tif r.ReadOnly != nil {\n\t\t// A writeMode is considered a read-only mode if it is Blocked or Protected.\n\t\tisReadOnlyMode := (r.WriteMode == WriteModeBlocked || r.WriteMode == WriteModeProtected)\n\n\t\t// The declared readOnly boolean must match the writeMode's behavior.\n\t\tif *r.ReadOnly != isReadOnlyMode {\n\t\t\treturn nil, fmt.Errorf(\"conflicting source configuration: readOnly is %v, but writeMode is %q\", *r.ReadOnly, r.WriteMode)\n\t\t}\n\t}\n\n\tif r.MaxQueryResultRows == 0 {\n\t\tr.MaxQueryResultRows = 50\n\t}\n\n\tif r.WriteMode == WriteModeProtected && strings.ToLower(r.UseClientOAuth) != \"false\" && r.UseClientOAuth != \"\" {\n\t\t// The protected mode only allows write operations to the session's temporary datasets.","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/bigquery/bigquery.go#L130-L166","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nwriteMode: readonly\n// after\nwriteMode: protected","handlingStrategy":"validation","validationCode":"var validWriteModes = map[string]bool{\"allowed\": true, \"blocked\": true, \"protected\": true}\nfunc validateWriteMode(mode string) error {\n\tif !validWriteModes[mode] {\n\t\treturn fmt.Errorf(\"writeMode %q must be allowed|blocked|protected\", mode)\n\t}\n\treturn nil\n}","typeGuard":"func isValidWriteMode(s string) bool {\n\treturn s == \"allowed\" || s == \"blocked\" || s == \"protected\"\n}","tryCatchPattern":"src, err := sourceRegistry.Initialize(ctx, cfg)\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid writeMode\") {\n\t\treturn fmt.Errorf(\"fix writeMode in config: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["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."],"tags":["config","validation","bigquery"],"backgroundTag":"invalid-config-value","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}