infiniflow/ragflow · error · ValueError

Keenable 'realtime' mode requires an API key

Error message

Keenable 'realtime' mode requires an API key

What it means

ValueError raised by KeenableSearch.check() at component configuration time. The tool supports mode 'pro' (default, works keyless against /v1/search/public) and 'realtime' (low latency, only on the keyed endpoint /v1/search). Selecting 'realtime' while api_key is empty is rejected immediately instead of failing at request time.

Source

Thrown at agent/tools/keenable.py:103

                    "required": False,
                },
            },
        }
        super().__init__()
        # A key is optional: blank uses the keyless public endpoint (free tier);
        # setting one lifts rate limits and enables the 'realtime' mode.
        self.api_key = ""
        # "pro" (default, deeper) or "realtime" (low latency; requires a key).
        self.mode = "pro"
        self.top_n = 10

    def check(self):
        self.check_valid_value(self.mode, "Keenable search mode should be in 'pro/realtime'", ["pro", "realtime"])
        self.check_positive_integer(self.top_n, "Top N")
        # 'realtime' is not available on the keyless public endpoint, so reject
        # the invalid combination at config time instead of failing at runtime.
        if self.mode == "realtime" and not (self.api_key or "").strip():
            raise ValueError("Keenable 'realtime' mode requires an API key")

    def get_input_form(self) -> dict[str, dict]:
        return {
            "query": {
                "name": "Query",
                "type": "line",
            },
            "site": {
                "name": "Site",
                "type": "line",
            },
        }


class KeenableSearch(ToolBase, ABC):
    component_name = "KeenableSearch"

    @timeout(int(os.environ.get("COMPONENT_EXEC_TIMEOUT", 12)))

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Set the component's api_key parameter to a valid Keenable key (it switches requests to /v1/search with X-API-Key).
  2. Or switch mode back to 'pro' to use the keyless public endpoint.
  3. Re-save/validate the component after changing either field so check() passes before the workflow runs.

Example fix

# before
component._param.mode = "realtime"
component._param.api_key = ""   # ValueError on check()

# after
component._param.mode = "realtime"
component._param.api_key = os.environ["KEENABLE_API_KEY"]
Defensive patterns

Strategy: validation

Validate before calling

def keenable_config_ok(mode: str, api_key: str) -> bool:
    return mode == "pro" or bool((api_key or "").strip())

Try / catch

try:
    component.check()
except ValueError as e:
    if "realtime" in str(e):
        component._param.mode = "pro"  # or supply a key
    raise

Prevention

When it happens

Trigger: Adding a Keenable search component to an agent canvas, setting mode='realtime', and leaving the api_key parameter blank; or clearing the key later without switching mode back to 'pro'.

Common situations: Users wanting lower-latency results without realizing realtime is a keyed feature; copied component JSON from another tenant with the key stripped; API-driven workflow creation that defaults api_key to '' while mode is persisted as 'realtime'.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/e0017bbdb88c01bb. Report an issue: GitHub.