{"record":{"id":"984022804c82d90b","repo":"googleapis/mcp-toolbox","slug":"invalid-source-for-q-tool-source-q-is-not-a-com-984022","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":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/looker/lookergetdashboards/lookergetdashboards.go","lineNumber":114,"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\tlogger, err := util.LoggerFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, util.NewClientServerError(\"unable to get logger from ctx\", http.StatusInternalServerError, err)\n\t}\n\tparamsMap := params.AsMap()\n\ttitle := paramsMap[\"title\"].(string)\n\ttitle_ptr := &title\n\tif *title_ptr == \"\" {\n\t\ttitle_ptr = nil","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookergetdashboards/lookergetdashboards.go#L96-L132","documentation":"ValidateSource for looker-get-dashboards confirms the attached source implements the Looker `compatibleSource` interface. When `source.(compatibleSource)` fails, the tool returns this error rather than proceeding, because Invoke needs Looker-specific source methods.","triggerScenarios":"Tool validation (startup or pre-invoke) where the sources.Source bound to the looker-get-dashboards tool is of a non-Looker kind.","commonSituations":"Wrong `source:` key in tools.yaml; typos in the source name resolving to another source; a custom Source missing the Looker interface; config drift after renaming sources between environments.","solutions":["Set the tool's `source:` to a looker-kind source in tools.yaml.","Fix source name typos so the intended Looker source resolves.","Implement compatibleSource on any custom source used with this tool.","Validate the config at startup to surface the mismatch before traffic."],"exampleFix":"// before\nsources:\n  my-http:\n    kind: http\ntools:\n  list-dashboards:\n    kind: looker-get-dashboards\n    source: my-http\n// after\nsources:\n  my-looker:\n    kind: looker\ntools:\n  list-dashboards:\n    kind: looker-get-dashboards\n    source: my-looker","handlingStrategy":"type-guard","validationCode":"if err := tool.ValidateSource(lookerSrc); err != nil {\n    return fmt.Errorf(\"config error: %w\", err)\n}","typeGuard":"func isLookerSource(s sources.Source) bool {\n    _, ok := s.(compatibleSource)\n    return ok\n}","tryCatchPattern":"if err := tool.ValidateSource(src); err != nil {\n    log.Fatalf(\"source incompatible with looker tool: %v\", err)\n}","preventionTips":["Call ValidateSource at startup for every tool/source pair.","Keep a mapping of tool kind to allowed source kinds in config review.","Fix source name typos before deployment; validate early.","Prefer reusing the registered looker source over custom implementations."],"tags":["go","looker","mcp-toolbox","source-binding","type-assertion"],"backgroundTag":"incompatible-tool-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"}