oraios/serena · error · ValueError

activation_command_timeout must be a number, got: {activatio

Error message

activation_command_timeout must be a number, got: {activation_command_timeout_raw}

What it means

_from_dict validates the project config's activation_command_timeout by casting it with float(). If the raw value is None or a non-numeric string (TypeError/ValueError), it raises ValueError stating the value must be a number. This timeout governs how long Serena waits for the language server activation command, so it must be numeric.

Source

Thrown at src/serena/config/serena_config.py:602

        for ls_str in data["language_servers"]:
            orig_language_str = ls_str
            try:
                ls_str = ls_str.lower()
                if ls_str in lang_name_mapping:
                    ls_str = lang_name_mapping[ls_str]
                ls_id = LanguageServerId(ls_str)
                ls_ids.append(ls_id)
            except ValueError as e:
                raise ValueError(
                    f"Invalid language server: '{orig_language_str}'.\nValid values are: {[l.value for l in LanguageServerId]}"
                ) from e

        # Validate activation_command_timeout
        activation_command_timeout_raw = data.get("activation_command_timeout", 180.0)
        try:
            activation_command_timeout = float(activation_command_timeout_raw)
        except (TypeError, ValueError) as e:
            raise ValueError(f"activation_command_timeout must be a number, got: {activation_command_timeout_raw}") from e
        if activation_command_timeout <= 0:
            raise ValueError(f"activation_command_timeout must be positive, got: {activation_command_timeout}")

        # Validate symbol_info_budget
        symbol_info_budget_raw = data["symbol_info_budget"]
        symbol_info_budget = symbol_info_budget_raw
        if symbol_info_budget is not None:
            try:
                symbol_info_budget = float(symbol_info_budget_raw)
            except (TypeError, ValueError) as e:
                raise ValueError(f"symbol_info_budget must be a number or null, got: {symbol_info_budget_raw}") from e
            if symbol_info_budget < 0:
                raise ValueError(f"symbol_info_budget cannot be negative, got: {symbol_info_budget}")

        language_backend_value = data.get("language_backend")
        language_backend = LanguageBackend.from_str(language_backend_value) if language_backend_value else None

        line_ending_value = data.get("line_ending")

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Set activation_command_timeout to a bare number in seconds, e.g. activation_command_timeout: 300
  2. If loading from env/CLI, convert explicitly: float(os.environ["ACTIVATION_TIMEOUT"]) before passing it
  3. Remove the key entirely to use the 180.0 default
  4. Also ensure the value is > 0, otherwise the follow-up 'must be positive' error fires

Example fix

// before (project.yml)
activation_command_timeout: "300s"
// after (project.yml)
activation_command_timeout: 300.0
Defensive patterns

Strategy: type-guard

Validate before calling

raw = data.get("activation_command_timeout", 180.0)
if raw is None or not isinstance(raw, (int, float)):
    raise TypeError(f"activation_command_timeout must be a number, got {raw!r}")

Type guard

def is_number(v) -> bool:
    return isinstance(v, (int, float)) and not isinstance(v, bool)

Try / catch

try:
    config = ProjectConfig.load(project_root)
except ValueError as e:
    if 'activation_command_timeout must be a number' in str(e):
        cfg = yaml.safe_load(project_yml)
        cfg['activation_command_timeout'] = 180.0
        # rewrite or fall back to defaults
    raise

Prevention

When it happens

Trigger: ProjectConfig.autogenerate(..., activation_command_timeout=None) or load() on a project.yml where activation_command_timeout is null, a string like 'five minutes' or '180s', or any non-numeric YAML scalar. Default is 180.0 when the key is absent.

Common situations: Hand-editing project.yml and writing activation_command_timeout: '300s' or leaving `activation_command_timeout:` with no value (YAML null); passing a string from an environment variable into autogenerate without conversion; pasting config where the unit was embedded in the value.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/83124fc36e820d8b. Report an issue: GitHub.