{"record":{"id":"6ccc37725f6ac332","repo":"getredash/redash","slug":"can-t-mix-mcf-and-ga-metrics","errorCode":null,"errorMessage":"Can't mix mcf: and ga: metrics.","messagePattern":"Can't mix mcf: and ga: metrics\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"redash/query_runner/google_analytics.py","lineNumber":168,"sourceCode":"\n    def test_connection(self):\n        try:\n            service = self._get_analytics_service()\n            service.management().accounts().list().execute()\n        except HttpError as e:\n            # Make sure we return a more readable error to the end user\n            raise Exception(e._get_reason())\n\n    def run_query(self, query, user):\n        logger.debug(\"Analytics is about to execute query: %s\", query)\n        try:\n            params = json_loads(query)\n        except Exception:\n            query_string = parse_qs(urlparse(query).query, keep_blank_values=True)\n            params = {k.replace(\"-\", \"_\"): \",\".join(v) for k, v in query_string.items()}\n\n        if \"mcf:\" in params[\"metrics\"] and \"ga:\" in params[\"metrics\"]:\n            raise Exception(\"Can't mix mcf: and ga: metrics.\")\n\n        if \"mcf:\" in params.get(\"dimensions\", \"\") and \"ga:\" in params.get(\"dimensions\", \"\"):\n            raise Exception(\"Can't mix mcf: and ga: dimensions.\")\n\n        if \"mcf:\" in params[\"metrics\"]:\n            api = self._get_analytics_service().data().mcf()\n        else:\n            api = self._get_analytics_service().data().ga()\n\n        if len(params) > 0:\n            try:\n                response = api.get(**params).execute()\n                data = parse_ga_response(response)\n                error = None\n            except HttpError as e:\n                # Make sure we return a more readable error to the end user\n                error = e._get_reason()\n                data = None","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/query_runner/google_analytics.py#L150-L186","documentation":"The GA runner splits queries between the ga: (core) and mcf: (Multi-Channel Funnels) endpoints. A single request cannot hit both, so if params['metrics'] contains both 'mcf:' and 'ga:' prefixes it raises this exception immediately after parsing the query.","triggerScenarios":"A query like {\"metrics\": \"ga:sessions,mcf:totalConversions\", ...} or URL form ?metrics=ga:sessions,mcf:totalConversions — any metrics list mixing both namespaces.","commonSituations":"Users combining core and MCF metrics thinking they are one API, or copy-pasting metric lists from GA UI reports that span both.","solutions":["Split into two queries: one with only ga: metrics, one with only mcf: metrics","Remove the mcf: metric if MCF data is not required"],"exampleFix":"// before\n{\"metrics\": \"ga:sessions,mcf:totalConversions\", \"dimensions\": \"ga:date\"}\n// after\n{\"metrics\": \"ga:sessions\", \"dimensions\": \"ga:date\"}","handlingStrategy":"validation","validationCode":"def metrics_are_consistent(metrics: str) -> bool:\n    has_mcf = \"mcf:\" in metrics\n    has_ga = \"ga:\" in metrics\n    return not (has_mcf and has_ga)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep ga: and mcf: metrics in separate Redash queries","Lint query params before saving","Remember MCF data lives on a different API"],"tags":["google-analytics","query-validation","mcf"],"backgroundTag":"invalid-query-parameters","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}