Config_entries.py.async_finish_flow(line 666) expects a field options in result, but data_entry_flow.py.sync_create_entry (line 376) creates a FlowResult without it

At the time of creating a new custom_component for a custom integration with a config flow with a form involved, after pushing the “Send button” in the config dialog after adding the integration by UI, a red “unkown error” appears on the top of it.

Looking at the core logs, they complain about config_entries.py.async_finish_flow(line 666) expecting a field options in result, but data_entry_flow.py.sync_create_entry (line 376) creating the FlowResult without it

Some log portion:

2021-07-11 10:50:56 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 422, in _handle_request
    resp = await self._request_handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_app.py", line 499, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.9/site-packages/aiohttp/web_middlewares.py", line 119, in impl
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 60, in security_filter_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 77, in forwarded_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 24, in request_context_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 78, in ban_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 144, in auth_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 135, in handle
    result = await result
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 155, in post
    return await super().post(request, flow_id)
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 63, in wrapper
    result = await method(view, request, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 109, in post
    result = await self._flow_mgr.async_configure(flow_id, data)
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 202, in async_configure
    result = await self._async_handle_step(flow, cur_step["step_id"], user_input)
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 295, in _async_handle_step
    result = await self.async_finish_flow(flow, result.copy())
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 666, in async_finish_flow
    options=result["options"],
KeyError: 'options'

We can’t help you when you don’t show us your code…

Thanks for your answer

Although I believe this could be a generic problem, here is my config_flow.py:

import voluptuous as vol
from homeassistant import data_entry_flow
from .const import DOMAIN
from homeassistant import config_entries, core, exceptions
from homeassistant.core import callback


@config_entries.HANDLERS.register(DOMAIN)
class ConfigFlow(data_entry_flow.FlowHandler):

    VERSION = 1

    unique_id = None

    show_advanced_options = False


    async def async_step_user(self, user_input=None):
        errors = {}
        options = {}
   
        if user_input is not None:
            return self.async_create_entry(
                title="Title of the entry",
                data=user_input
            )

        # Specify items in the order they are to be displayed in the UI
        data_schema = {
            vol.Required("username", default="user"): str,
            vol.Required("password", default="pass"): str,
        }

        return self.async_show_form(step_id="user", data_schema=vol.Schema(data_schema))
    
    async def async_set_unique_id(device_unique_id):
        self.unique_id = device_unique_id

This is my manifest.json:

{
  "domain": "jam_ufd",
  "name": "JAM Integration for UFD",
  "documentation": "https://www.example.com",
  "dependencies": [],
  "codeowners": [],
  "requirements": [],
  "iot_class": "cloud_polling",
  "version": "0.1.0",
  "config_flow": true
}

This is my init.py:

import asyncio

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

DOMAIN = "jam_ufd"

ATTR_NAME = "name"
DEFAULT_NAME = "World"

def setup(hass: HomeAssistant, config: dict):
    """Set up is called when Home Assistant is loading our component."""

    def handle_get_ufd_reading(call):
        """Handle the service call."""
        name = call.data.get(ATTR_NAME, DEFAULT_NAME)

        hass.states.set("jam_ufd.getUfdReading", name)

    hass.services.register(DOMAIN, "getUfdReading", handle_get_ufd_reading)

    # Return boolean to indicate that initialization was successfully.
    return True

And this is my const.py:

"""Constants for breaking_changes."""
# Base component constants
DOMAIN = "jam_ufd"
DOMAIN_DATA = "{}_data".format(DOMAIN)
INTEGRATION_VERSION = "v0.0.1"


STARTUP = f"""
-------------------------------------------------------------------
{DOMAIN}
Version: {INTEGRATION_VERSION}
This is a custom component
If you have any issues with this you need to open an issue here:
https://github.com/custom-components/breaking_changes/issues
-------------------------------------------------------------------
"""

# Configuration
CONF_USER_NAME = "username"
CONF_PASSWORD = "password"

Already seen the problem.

In config_flow, instead of:

@config_entries.HANDLERS.register(DOMAIN)
class ConfigFlow(data_entry_flow.FlowHandler):

it has to be:

class JamConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):