{"record":{"id":"996a2a809510a0cd","repo":"googleapis/mcp-toolbox","slug":"invalid-source-for-q-tool-source-q-is-not-a-com-996a2a","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/lookermakedashboard/lookermakedashboard.go","lineNumber":115,"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\tlogger.DebugContext(ctx, \"params = \", params)\n\n\tsdk, err := source.GetLookerSDK(ctx, string(accessToken))\n\tif err != nil {\n\t\treturn nil, util.NewClientServerError(\"error getting sdk\", http.StatusInternalServerError, err)","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookermakedashboard/lookermakedashboard.go#L97-L133","documentation":"ValidateSource for looker-make-dashboard asserts the incoming sources.Source implements compatibleSource (Looker SDK methods). Any other source kind fails the assertion and produces this error, preventing the dashboard tool from being used with an incompatible backend.","triggerScenarios":"Invoking Tool.ValidateSource(source) where source is not a Looker source — typically a tools.yaml `source:` field naming a non-Looker source, or the wrong Source object passed during programmatic setup.","commonSituations":"Copy-pasted tool configs retaining a database source name; source renamed/refactored so it no longer satisfies the Looker interface; test harness supplying a partial stub source.","solutions":["Point the tool's `source` at a source of kind looker.","Verify the source name exists under `sources` and is the intended Looker instance.","For custom sources, implement UseClientAuthorization, GetAuthTokenHeaderName, LookerApiSettings, and GetLookerSDK."],"exampleFix":"# before\ntools:\n  make-dashboard:\n    kind: looker-make-dashboard\n    source: mysql-src\n\n# after\ntools:\n  make-dashboard:\n    kind: looker-make-dashboard\n    source: looker-src","handlingStrategy":"type-guard","validationCode":"// Go: guard before using the tool with a source\nif err := tool.ValidateSource(src); err != nil {\n    return fmt.Errorf(\"looker-make-dashboard requires a looker source: %w\", err)\n}","typeGuard":"func isLookerSource(s sources.Source) bool {\n    _, ok := s.(interface {\n        UseClientAuthorization() bool\n        GetAuthTokenHeaderName() string\n        LookerApiSettings() *rtl.ApiSettings\n        GetLookerSDK(context.Context, string) (*v4.LookerSDK, error)\n    })\n    return ok\n}","tryCatchPattern":"if err := tool.ValidateSource(src); err != nil {\n    if strings.Contains(err.Error(), \"not a compatible type\") {\n        return fmt.Errorf(\"check tools.yaml: source must be kind looker: %w\", err)\n    }\n    return err\n}","preventionTips":["Ensure the tool's `source:` names a looker-kind source.","Call ValidateSource for all tools during server bootstrap.","Avoid reusing database source names in Looker tool configs.","Re-run config-loading tests after any source refactor."],"tags":["go","looker","type-assertion","configuration"],"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"}