{"record":{"id":"0e980e5e3f1e12eb","repo":"googleapis/mcp-toolbox","slug":"invalid-source-for-q-tool-source-q-is-not-a-com-0e980e","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/lookerdeleteagent/lookerdeleteagent.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\n\tsdk, err := source.GetLookerSDK(ctx, string(accessToken))\n\tif err != nil {\n\t\treturn nil, util.NewClientServerError(fmt.Sprintf(\"error getting sdk: %v\", err), http.StatusInternalServerError, err)\n\t}","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookerdeleteagent/lookerdeleteagent.go#L96-L132","documentation":"Looker tool ValidateSource checks that the configured source implements the tool's private compatibleSource interface (UseClientAuthorization, GetAuthTokenHeaderName, LookerApiSettings, GetLookerSDK). If the source bound to the tool in the toolbox config is not a Looker source, the Go type assertion fails and this error is returned. It is a config-shape mismatch, not a runtime/network failure.","triggerScenarios":"Calling ValidateSource (directly or via tool resolution at server startup) when the tool's YAML `source:` points to a non-Looker source (e.g. a postgres or http source), or to a Looker-like source that does not implement GetLookerSDK/LookerApiSettings.","commonSituations":"Copy-pasting a tool definition and forgetting to change its `source` field; renaming a source in the config so the tool silently binds to the wrong one; mixing sources in a multi-source config file; upgrading the toolbox after a Looker source interface change.","solutions":["Set the tool's `source` field in the YAML config to the name of a Looker source (kind: looker).","Verify the referenced source actually initializes as a Looker source (check `kind`/`type` in the sources section).","If writing a custom source, implement all four methods of compatibleSource: UseClientAuthorization, GetAuthTokenHeaderName, LookerApiSettings, GetLookerSDK."],"exampleFix":"# before\ntools:\n  delete-agent:\n    kind: looker-delete-agent\n    source: my-postgres\n\n# after\ntools:\n  delete-agent:\n    kind: looker-delete-agent\n    source: my-looker","handlingStrategy":"type-guard","validationCode":"if _, ok := src.(interface {\n\tUseClientAuthorization() bool\n\tGetAuthTokenHeaderName() string\n\tLookerApiSettings() *rtl.ApiSettings\n\tGetLookerSDK(context.Context, string) (*v4.LookerSDK, error)\n}); !ok {\n\treturn fmt.Errorf(\"source %T is not a Looker source; check tool's `source` field\", src)\n}","typeGuard":"func isCompatibleLookerSource(s sources.Source) bool {\n\t_, ok := s.(interface {\n\t\tUseClientAuthorization() bool\n\t\tGetAuthTokenHeaderName() string\n\t\tLookerApiSettings() *rtl.ApiSettings\n\t\tGetLookerSDK(context.Context, string) (*v4.LookerSDK, error)\n\t})\n\treturn ok\n}","tryCatchPattern":"if err := tool.ValidateSource(src); err != nil {\n\t// log config source name and fix the tool's `source` YAML field\n\treturn fmt.Errorf(\"binding looker tool failed: %w\", err)\n}","preventionTips":["Always set a Looker tool's `source` to a source declared with kind: looker.","Keep source names unique and grep the config for the referenced name before startup.","Validate the full config at deploy time so source/tool mismatches fail before serving traffic.","Re-check tool-source pairings after renaming or deleting any source."],"tags":["go","looker","source-validation","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"}