{"record":{"id":"5156a5259693018c","repo":"googleapis/mcp-toolbox","slug":"invalid-source-for-q-tool-source-q-is-not-a-com-5156a5","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/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go","lineNumber":109,"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\tmapParams := params.AsMap()\n\tconn, ok := mapParams[\"conn\"].(string)\n\tif !ok {\n\t\treturn nil, util.NewAgentError(fmt.Sprintf(\"'conn' must be a string, got %T\", mapParams[\"conn\"]), nil)\n\t}","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookergetconnectiontablecolumns/lookergetconnectiontablecolumns.go#L91-L127","documentation":"This error is returned by the looker-get-connection-table-columns tool's ValidateSource when the sources.Source instance passed to the tool does not implement the tool's compatibleSource interface (UseClientAuthorization() bool, GetAuthTokenHeaderName() string, LookerApiSettings() *rtl.ApiSettings). The toolbox only wires Looker tools to a Looker source, so this means the tool was bound to a source of the wrong kind (e.g. a Postgres or other database source instead of a Looker source). It is a configuration/wiring error, not a runtime data error.","triggerScenarios":"Calling ValidateSource (directly or via server/tool startup validation) with a source whose concrete type does not satisfy compatibleSource — for example binding looker-get-connection-table-columns to a non-Looker source, or using a source that implements sources.Source but not the Looker-specific interface methods.","commonSituations":"Hand-writing a tools.yaml where the tool's source field points at the wrong source definition; refactoring/renaming sources and mis-wiring; programmatically constructing a tool + source pair in tests with a stub source that lacks LookerApiSettings/UseClientAuthorization/GetAuthTokenHeaderName; upgrading after the compatibleSource interface gained new methods so an older custom source no longer satisfies it.","solutions":["Point the tool's `source` field in your config at a Looker source definition (kind: looker), not a database source.","If using a custom/stub source, implement the full compatibleSource interface: UseClientAuthorization() bool, GetAuthTokenHeaderName() string, LookerApiSettings() *rtl.ApiSettings.","Use prebuilt Looker configs or copy the source block from the Looker docs so source kind and tool match.","If the interface changed after an upgrade, update your source implementation to satisfy the new methods (compiler will list them)."],"exampleFix":"# before (tools.yaml)\ntools:\n  get-columns:\n    kind: looker-get-connection-table-columns\n    source: my-postgres-source\n# after\nsources:\n  my-looker:\n    kind: looker\n    ...\ntools:\n  get-columns:\n    kind: looker-get-connection-table-columns\n    source: my-looker","handlingStrategy":"type-guard","validationCode":"if _, ok := source.(lookergetconnectiontablecolumns.CompatibleSource); !ok {\n    return fmt.Errorf(\"tool %q requires a Looker source; got %T\", toolName, source)\n}","typeGuard":"func isCompatibleLookerSource(s sources.Source) bool {\n    _, ok := s.(interface {\n        UseClientAuthorization() bool\n        GetAuthTokenHeaderName() string\n        LookerApiSettings() *rtl.ApiSettings\n    })\n    return ok\n}","tryCatchPattern":"if err := tool.ValidateSource(src); err != nil {\n    log.Fatalf(\"tool/source mismatch: %v\", err) // fail fast at startup\n}","preventionTips":["Bind Looker tools only to sources with kind: looker in tools.yaml.","Run server startup validation (ValidateSource) before accepting traffic.","Keep a compile-time assertion in Go: var _ compatibleSource = looker.Source{}.","When copying tool configs, always copy the source block from the same doc page."],"tags":["go","looker","source-type-mismatch","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"}