{"record":{"id":"6006ecd2571e7a71","repo":"home-assistant/core","slug":"channel-not-found","errorCode":"channel_not_found","errorMessage":"There is no {channel_type} channel at this site.","messagePattern":"There is no (.+?) channel at this site\\.","errorType":"validation","errorClass":"ServiceValidationError","httpStatus":null,"severity":"error","filePath":"homeassistant/components/amberelectric/services.py","lineNumber":44,"sourceCode":"from .coordinator import AmberConfigEntry\nfrom .helpers import format_cents_to_dollars, normalize_descriptor\n\nGET_FORECASTS_SCHEMA = vol.Schema(\n    {\n        ATTR_CONFIG_ENTRY_ID: ConfigEntrySelector({\"integration\": DOMAIN}),\n        ATTR_CHANNEL_TYPE: vol.In(\n            [GENERAL_CHANNEL, CONTROLLED_LOAD_CHANNEL, FEED_IN_CHANNEL]\n        ),\n    }\n)\n\n\ndef get_forecasts(channel_type: str, data: dict) -> list[JsonValueType]:\n    \"\"\"Return an array of forecasts.\"\"\"\n    results: list[JsonValueType] = []\n\n    if channel_type not in data[\"forecasts\"]:\n        raise ServiceValidationError(\n            translation_domain=DOMAIN,\n            translation_key=\"channel_not_found\",\n            translation_placeholders={\"channel_type\": channel_type},\n        )\n\n    intervals = data[\"forecasts\"][channel_type]\n\n    for interval in intervals:\n        datum = {}\n        datum[\"duration\"] = interval.duration\n        datum[\"date\"] = interval.var_date.isoformat()\n        datum[\"nem_date\"] = interval.nem_time.isoformat()\n        datum[\"per_kwh\"] = format_cents_to_dollars(interval.per_kwh)\n        if interval.channel_type == ChannelType.FEEDIN:\n            datum[\"per_kwh\"] = datum[\"per_kwh\"] * -1\n        datum[\"spot_per_kwh\"] = format_cents_to_dollars(interval.spot_per_kwh)\n        datum[\"start_time\"] = interval.start_time.isoformat()\n        datum[\"end_time\"] = interval.end_time.isoformat()","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/amberelectric/services.py#L26-L62","documentation":"ServiceValidationError with translation key amberelectric/channel_not_found, raised by get_forecasts() when the requested channel_type (general, controlled_load, or feed_in) has no key in data['forecasts'] — the site has no forecast intervals for that channel, so the forecast service cannot return anything.","triggerScenarios":"Calling the get_forecasts service with ATTR_CHANNEL_TYPE=controlled_load or feed_in on a site whose coordinator data contains no forecast entries for that channel (only general present), because the Amber tariff lacks that channel.","commonSituations":"Users without a controlled-load or solar feed-in tariff requesting those forecast services, or calling the service before the coordinator has fetched data containing the channel.","solutions":["Request forecasts only for channels your Amber site actually has (check the Amber app tariff channels)","Use 'general' — every site with the integration set up must have it","Ensure the integration has completed at least one successful data update before calling the forecast service","Reconfigure the site selection if the wrong site was chosen"],"exampleFix":"// before\naction:\n  domain: amberelectric\n  data:\n    channel_type: controlled_load  # site has no controlled load channel\n// after\naction:\n  domain: amberelectric\n  data:\n    channel_type: general  # channel present in data[\"forecasts\"]","handlingStrategy":"validation","validationCode":"if channel_type not in data[\"forecasts\"]:\n    _LOGGER.warning(\n        \"Channel %s has no forecasts (available: %s)\",\n        channel_type, list(data[\"forecasts\"]),\n    )\n    return","typeGuard":"def has_forecast_channel(data: dict, channel_type: str) -> bool:\n    \"\"\"True when the coordinator data has forecasts for channel_type.\"\"\"\n    return channel_type in data.get(\"forecasts\", {})","tryCatchPattern":"try:\n    await hass.services.async_call(DOMAIN, \"get_forecasts\", service_data, blocking=True)\nexcept ServiceValidationError as err:\n    if err.translation_key == \"channel_not_found\":\n        _LOGGER.warning(\"Site has no %s channel; use a channel your tariff provides\", channel_type)","preventionTips":["Query only channels that exist in your Amber tariff (check the app)","Check data['forecasts'] keys before requesting a channel in custom code","Ensure the coordinator has completed a successful refresh before calling forecast services"],"tags":["amberelectric","service-call","validation","tariff","homeassistant"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}