{"record":{"id":"51e81686cce6cdc3","repo":"googleapis/mcp-toolbox","slug":"cannot-unmarshal-t-into-stringorstringslice","errorCode":null,"errorMessage":"cannot unmarshal %T into StringOrStringSlice","messagePattern":"cannot unmarshal %T into StringOrStringSlice","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/bigquery/bigquery.go","lineNumber":131,"sourceCode":"\tvar v any\n\tif err := unmarshal(&v); err != nil {\n\t\treturn err\n\t}\n\tswitch val := v.(type) {\n\tcase string:\n\t\t*s = strings.Split(val, \",\")\n\t\treturn nil\n\tcase []any:\n\t\tfor _, item := range val {\n\t\t\tif str, ok := item.(string); ok {\n\t\t\t\t*s = append(*s, str)\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"element in sequence is not a string: %v\", item)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\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}","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/bigquery/bigquery.go#L113-L149","documentation":"This error comes from the custom UnmarshalYAML implementation of the StringOrStringSlice type in the BigQuery source config. StringOrStringSlice accepts either a single YAML string or a sequence of strings; if the YAML value is neither (e.g. a number, boolean, map, or a sequence containing non-strings), the unmarshaller returns this error. It is thrown at config-parse time before any connection is made.","triggerScenarios":"Parsing a BigQuery source YAML config where a field of type StringOrStringSlice (e.g. allowedDatasets) is given a YAML scalar of non-string type (integer, bool), a nested mapping, or a list whose elements are not all strings.","commonSituations":"Writing `allowedDatasets: 123` or `allowedDatasets: [mydataset, 42]` in tools.yaml; quoting mistakes that turn a list into a map; typos producing a nested structure where a string list was expected.","solutions":["Check the YAML field: it must be a single string or a list of strings.","Quote every element in the list so YAML does not parse it as a number or boolean (e.g. [\"123\", \"true\"]).","If you need a single value, write it as a plain string instead of a nested list/map."],"exampleFix":"// before (invalid: non-string element)\nallowedDatasets:\n  - 12345\n  - mydataset\n// after\nallowedDatasets:\n  - \"12345\"\n  - mydataset","handlingStrategy":"validation","validationCode":"func validateStringOrStringSlice(v interface{}) error {\n\tnormalize := func(s interface{}) error {\n\t\t_, ok := s.(string)\n\t\tif !ok { return fmt.Errorf(\"not a string: %v\", s) }\n\t\treturn nil\n\t}\n\tswitch t := v.(type) {\n\tcase string, nil:\n\t\treturn nil\n\tcase []interface{}:\n\t\tfor _, item := range t {\n\t\t\tif err := normalize(item); err != nil { return err }\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"cannot unmarshal %T into StringOrStringSlice\", v)\n\t}\n}","typeGuard":"func isStringOrStringSlice(v interface{}) bool {\n\tswitch t := v.(type) {\n\tcase string:\n\t\treturn true\n\tcase []interface{}:\n\t\tfor _, item := range t {\n\t\t\tif _, ok := item.(string); !ok { return false }\n\t\t}\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}","tryCatchPattern":"var cfg Config\nif err := yaml.Unmarshal(data, &cfg); err != nil {\n\tif strings.Contains(err.Error(), \"StringOrStringSlice\") {\n\t\tlog.Fatalf(\"config field must be a string or list of strings: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Quote ambiguous YAML scalars (numeric-looking IDs, booleans) in tools.yaml.","Run the config through a YAML linter before deployment.","Keep list elements on their own lines with proper '- ' syntax."],"tags":["yaml","config","unmarshal","bigquery"],"backgroundTag":"yaml-unmarshal-type-mismatch","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"}