{"record":{"id":"d5732ddc40b12d84","repo":"googleapis/mcp-toolbox","slug":"error-fetching-lookml-models-w","errorCode":null,"errorMessage":"error fetching LookML models: %w","messagePattern":"error fetching LookML models: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go","lineNumber":218,"sourceCode":"\ttimeframe  int\n\tminQueries int\n}\n\nfunc (t *vacuumTool) models(ctx context.Context, project, model string) ([]map[string]interface{}, error) {\n\tlogger, err := util.LoggerFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get logger from ctx: %s\", err)\n\t}\n\tlogger.InfoContext(ctx, \"Vacuuming models...\")\n\n\tusedModels, err := t.getUsedModels(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlookmlModels, err := t.SdkClient.AllLookmlModels(v4.RequestAllLookmlModels{}, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error fetching LookML models: %w\", err)\n\t}\n\n\tvar results []map[string]interface{}\n\tfor _, m := range lookmlModels {\n\t\tif (project == \"\" || (m.ProjectName != nil && *m.ProjectName == project)) &&\n\t\t\t(model == \"\" || (m.Name != nil && *m.Name == model)) {\n\n\t\t\tqueryCount := 0\n\t\t\tif qc, ok := usedModels[*m.Name]; ok {\n\t\t\t\tqueryCount = qc\n\t\t\t}\n\n\t\t\tunusedExplores, err := t.getUnusedExplores(ctx, *m.Name)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tresults = append(results, map[string]interface{}{","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/looker/lookerhealthvacuum/lookerhealthvacuum.go#L200-L236","documentation":"vacuumTool.models calls the Looker SDK's AllLookmlModels(v4.RequestAllLookmlModels{}, nil) to list all LookML models for the connected instance. Any SDK-level failure (network error, auth rejection, API error response) is wrapped as \"error fetching LookML models: %w\" and aborts the models vacuum step. The root cause is always contained in the wrapped %w error.","triggerScenarios":"t.SdkClient.AllLookmlModels returns a non-nil error: Looker API unreachable, expired/invalid client credentials (client_id/client_secret), insufficient permissions for the API user, 429 rate limiting, or a malformed base URL in the looker source config.","commonSituations":"Looker instance behind VPN/firewall unreachable from the toolbox host; API token revoked or rotated; service account lacking view/manage access to LookML; TLS/certificate issues with self-hosted Looker; wrong looker.base_url (http vs https).","solutions":["Unwrap and inspect the wrapped error to identify the HTTP status or transport failure.","Verify looker source config: base_url and client credentials are correct and the instance is reachable (curl the /login endpoint).","Confirm the API user has permissions to list LookML models.","Retry on 429/5xx after backing off; check Looker instance health."],"exampleFix":"// before — no diagnostics\nlookmlModels, err := t.SdkClient.AllLookmlModels(v4.RequestAllLookmlModels{}, nil)\n\n// after — check connectivity/credentials before retry\nlookmlModels, err := t.SdkClient.AllLookmlModels(v4.RequestAllLookmlModels{}, nil)\nif err != nil {\n    logger.ErrorContext(ctx, \"AllLookmlModels failed\", \"err\", err)\n    return nil, fmt.Errorf(\"error fetching LookML models: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// pre-flight check before vacuuming\nresp, err := http.Get(strings.TrimSuffix(baseURL, \"/\") + \"/login\")\nif err != nil || resp.StatusCode >= 500 {\n    return fmt.Errorf(\"looker instance unreachable: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"lookmlModels, err := sdk.AllLookmlModels(v4.RequestAllLookmlModels{}, nil)\nvar apiErr *lookersdk.APIError\nif errors.As(err, &apiErr) && (apiErr.Is429() || apiErr.Response.StatusCode >= 500) {\n    // retry with exponential backoff\n}\nif err != nil {\n    return fmt.Errorf(\"error fetching LookML models: %w\", err)\n}","preventionTips":["Verify looker base_url and credentials with a direct API call before deploying.","Grant the API service account permission to list LookML models.","Rotate and re-test credentials as part of secrets management.","Add retry with backoff for 429 and 5xx responses."],"tags":["looker","api","network","sdk"],"backgroundTag":"looker-api-request-failed","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"}