{"record":{"id":"81a6e00324969fe6","repo":"googleapis/mcp-toolbox","slug":"invalid-source-for-q-tool-source-q-is-not-a-com-81a6e0","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/looker/lookergetprojectdirectories/lookergetprojectdirectories.go","lineNumber":142,"sourceCode":"\tif !ok {\n\t\treturn nil, util.NewAgentError(fmt.Sprintf(\"'project_id' must be a string, got %T\", mapParams[\"project_id\"]), nil)\n\t}\n\n\tresp, err := lookercommon.GetProjectDirectories(sdk, projectId, source.LookerApiSettings())\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"status=401\") {\n\t\t\treturn nil, util.NewClientServerError(\"unauthorized error\", http.StatusUnauthorized, err)\n\t\t}\n\t\treturn nil, util.ProcessGeneralError(err)\n\t}\n\n\treturn resp, nil\n}\n\nfunc (t Tool) RequiresClientAuthorization(source sources.Source) (bool, error) {\n\ts, ok := source.(compatibleSource)\n\tif !ok {\n\t\treturn false, fmt.Errorf(\"invalid source for %q tool: source %q is not a compatible type\", t.Cfg.Type, t.Cfg.Source)\n\t}\n\treturn s.UseClientAuthorization(), nil\n}\n\nfunc (t Tool) GetAuthTokenHeaderName(source sources.Source) (string, error) {\n\ts, 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 s.GetAuthTokenHeaderName(), nil\n}\n","sourceCodeStart":124,"sourceCodeEnd":154,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookergetprojectdirectories/lookergetprojectdirectories.go#L124-L154","documentation":"RequiresClientAuthorization on looker-get-project-directories returns the Looker source's client-authorization setting, but only after asserting `source.(compatibleSource)`. A non-Looker source triggers this error because authorization behavior cannot be safely queried from it.","triggerScenarios":"Server auth handling calls RequiresClientAuthorization for a looker-get-project-directories tool whose configured source is not a Looker source.","commonSituations":"Wrong source binding in tools.yaml; test mocks missing the interface; environment-specific configs (dev/staging/prod) drifting so some bind non-Looker sources.","solutions":["Point the tool at a looker-kind source in tools.yaml.","Make test doubles implement compatibleSource or embed the real source.","Audit all environment configs for correct Looker source bindings.","Reload/restart the toolbox after fixing bindings."],"exampleFix":"// before\n    kind: looker-get-project-directories\n    source: api-gateway\n// after\n    kind: looker-get-project-directories\n    source: my-looker","handlingStrategy":"type-guard","validationCode":"if _, ok := src.(lookercommon.CompatibleSource); !ok {\n    return errors.New(\"looker-get-project-directories requires a looker source\")\n}","typeGuard":"func isLookerSource(s sources.Source) bool {\n    _, ok := s.(compatibleSource)\n    return ok\n}","tryCatchPattern":"requiresAuth, err := tool.RequiresClientAuthorization(src)\nif err != nil {\n    return false, fmt.Errorf(\"client auth check failed (wrong source kind?): %w\", err)\n}","preventionTips":["Confirm looker tools reference looker sources in all environments.","Run startup validation of every tool's source interface.","Avoid mock sources in tests that only partially implement Source.","Version-control and review tools.yaml changes like code."],"tags":["go","looker","mcp-toolbox","auth","source-binding"],"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"}