{"record":{"id":"d31ca96352592021","repo":"googleapis/mcp-toolbox","slug":"invalid-source-for-q-tool-source-q-is-not-a-com-d31ca9","errorCode":null,"errorMessage":"invalid source for %q tool: source %q is not a compatible type","messagePattern":"invalid source for %q tool: source %q is not a compatible type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go","lineNumber":103,"sourceCode":"// validate interface\nvar _ tools.Tool = Tool{}\n\ntype Tool struct {\n\ttools.BaseTool[Config]\n}\n\nfunc (t Tool) GetSourceName() string {\n\treturn t.Cfg.Source\n}\n\nfunc (t Tool) ToConfig() tools.ToolConfig {\n\treturn t.Cfg\n}\n\nfunc (t Tool) ValidateSource(source sources.Source) error {\n\t_, ok := source.(compatibleSource)\n\tif !ok {\n\t\treturn fmt.Errorf(\"invalid source for %q tool: source %q is not a compatible type\", t.Cfg.Type, t.Cfg.Source)\n\t}\n\treturn nil\n}\n\nfunc (t Tool) Invoke(ctx context.Context, s sources.Source, params parameters.ParamValues, accessToken tools.AccessToken) (any, util.ToolboxError) {\n\tsource, ok := s.(compatibleSource)\n\tif !ok {\n\t\treturn nil, util.NewClientServerError(\"source used is not compatible with the tool\", http.StatusInternalServerError, nil)\n\t}\n\tmapParams := params.AsMap()\n\tdocumentPathsRaw, ok := mapParams[documentPathsKey].([]any)\n\tif !ok {\n\t\treturn nil, util.NewAgentError(fmt.Sprintf(\"invalid or missing '%s' parameter; expected an array\", documentPathsKey), nil)\n\t}\n\tif len(documentPathsRaw) == 0 {\n\t\treturn nil, util.NewAgentError(fmt.Sprintf(\"'%s' parameter cannot be empty\", documentPathsKey), nil)\n\t}\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/firestore/firestoredeletedocuments/firestoredeletedocuments.go#L85-L121","documentation":"Tool.ValidateSource type-asserts the provided sources.Source against the tool's compatibleSource interface. If the source wired to this firestore-delete-documents tool does not implement that interface (i.e., is not the Firestore source), the tool refuses to run. This is a wiring/manifest validation guard that fires before any Firestore API call is made.","triggerScenarios":"Calling toolset/manifest resolution or Invoke with a source registered for the tool whose concrete Go type does not satisfy compatibleSource (e.g., a postgres or cloudsql source instead of the firestore source).","commonSituations":"YAML configs where the tool's `source:` field points at a source of a different kind; programmatic construction of the tool with the wrong sources.Source; copy-pasting a tool block between sources without updating the source name.","solutions":["Set the tool's `source:` field in the YAML to the name of a firestore-kind source.","Verify the referenced source's `kind: firestore` matches the tool's expected type.","If constructing programmatically, pass the *firestore.Source instance (not another source) to ValidateSource/Invoke."],"exampleFix":"// before\ntools:\n  delete_doc:\n    kind: firestore-delete-documents\n    source: my-postgres\n// after\ntools:\n  delete_doc:\n    kind: firestore-delete-documents\n    source: my-firestore","handlingStrategy":"type-guard","validationCode":"func validateFirestoreSource(name string, src sources.Source) error {\n\tif _, ok := src.(interface{ FirestoreClient() *firestore.Client }); !ok {\n\t\treturn fmt.Errorf(\"tool requires a firestore source, got %T\", src)\n\t}\n\treturn nil\n}","typeGuard":"func isCompatibleFirestoreSource(s sources.Source) bool {\n\t_, ok := s.(firestore.CompatibleSource)\n\treturn ok\n}","tryCatchPattern":"if err := tool.ValidateSource(src); err != nil {\n\t// handle: wrong source bound to tool\n\tlog.Printf(\"config error: %v\", err)\n\treturn err\n}","preventionTips":["Keep a 1:1 mapping between firestore-* tools and firestore-kind sources in YAML.","Validate the whole config with `toolbox --dry-run` style startup before deploying.","Use distinct, descriptive source names so cross-wiring is obvious in review."],"tags":["firestore","source-validation","config"],"backgroundTag":"incompatible-source-type","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"}