{"record":{"id":"5fb9d25cda64ca1b","repo":"nexu-io/open-design","slug":"no-x-backend-is-available","errorCode":null,"errorMessage":"No X backend is available.","messagePattern":"No X backend is available\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"design-templates/last30days/scripts/lib/pipeline.py","lineNumber":912,"sourceCode":"        backend = runtime.x_search_backend or env.get_x_source(config)\n        if backend == \"bird\":\n            result = bird_x.search_x(subquery.search_query, from_date, to_date, depth=depth)\n            return bird_x.parse_bird_response(result, query=subquery.search_query), {}\n        if backend == \"xai\":\n            model = config.get(\"LAST30DAYS_X_MODEL\") or config.get(\"XAI_MODEL_PIN\") or providers.XAI_DEFAULT\n            result = xai_x.search_x(\n                config[\"XAI_API_KEY\"],\n                model,\n                subquery.search_query,\n                from_date,\n                to_date,\n                depth=depth,\n            )\n            return xai_x.parse_x_response(result), {}\n        if backend == \"xurl\":\n            result = xurl_x.search_x(subquery.search_query, depth=depth)\n            return xurl_x.parse_x_response(result, topic=subquery.search_query), {}\n        raise RuntimeError(\"No X backend is available.\")\n    if source == \"youtube\":\n        # Use raw_topic so expand_youtube_queries() generates diverse variants\n        # from the original user topic, not the planner's narrowed search_query.\n        yt_query = raw_topic or subquery.search_query\n        result = None\n        # Try yt-dlp first, fall back to SC YouTube if it fails or isn't installed\n        if which(\"yt-dlp\"):\n            try:\n                result = youtube_yt.search_and_transcribe(yt_query, from_date, to_date, depth=depth)\n            except Exception:\n                result = None\n        if (result is None or not result.get(\"items\")) and env.is_youtube_sc_available(config):\n            sc_token = config.get(\"SCRAPECREATORS_API_KEY\", \"\")\n            result = youtube_yt.search_youtube_sc(yt_query, from_date, to_date, depth=depth, token=sc_token)\n        if result is None:\n            result = {\"items\": []}\n        # Enrich top videos with comments when SC key is available\n        items = youtube_yt.parse_youtube_response(result)","sourceCodeStart":894,"sourceCodeEnd":930,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/design-templates/last30days/scripts/lib/pipeline.py#L894-L930","documentation":"Thrown by the X-source dispatch in pipeline.py when the resolved `runtime.x_search_backend` (or `env.get_x_source(config)`) does not match any of the handled backends ('bird', 'xai', 'xurl'). The code reaches the trailing RuntimeError only because every backend branch was skipped, meaning no X/Twitter data source is available for this run.","triggerScenarios":"Calling stream_results with source=='x' while runtime.x_search_backend is None or an unrecognized string. This happens when XAI_API_KEY is unset, AUTH_TOKEN/CT0 cookies are absent, and the xurl CLI is not installed/authenticated, so env.get_x_source returns None.","commonSituations":"Running the last30days pipeline on a fresh checkout with no .env credentials. Setting LAST30DAYS_X_BACKEND to a typo like 'bird2' or 'twiter'. Disabling xurl CLI so get_x_source_with_method returns ('none') which is not a handled branch.","solutions":["Provide an X credential: set XAI_API_KEY (preferred) OR both AUTH_TOKEN and CT0 cookies for the bird backend.","Install and authenticate the xurl CLI so env.get_x_source falls through to the oauth2 'xurl' branch.","Verify LAST30DAYS_X_BACKEND is one of {xai, bird} or unset; remove any typo.","If X is optional, drop 'x' from the SubQuery.sources so the planner never schedules an X retrieval."],"exampleFix":"# before\nXAI_API_KEY=\nLAST30DAYS_X_BACKEND=birb\n\n# after\nXAI_API_KEY=xai-xxxxxxxx\nLAST30DAYS_X_BACKEND=xai","handlingStrategy":"validation","validationCode":"from lib import env, providers\n\ndef assert_x_backend_available(config):\n    runtime_backend = providers._resolve_x_backend(config)\n    resolved = runtime_backend or env.get_x_source(config)\n    if resolved not in {\"bird\", \"xai\", \"xurl\"}:\n        raise RuntimeError(\n            \"No X backend available; set XAI_API_KEY or AUTH_TOKEN+CT0, \"\n            \"or install/authenticate the xurl CLI.\"\n        )\n    return resolved","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Resolve and validate the X backend once at startup (pre-flight) rather than per subquery.","Keep 'x' out of SubQuery.sources when no X credential is configured so the planner never schedules it.","Document the backend precedence (xai > bird-with-cookies > xurl) in your runbook so operators know which knob to flip."],"tags":["config","backend-selection","x-twitter","credentials"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}