{"record":{"id":"5182668ae9c45864","repo":"oraios/serena","slug":"symbol-info-budget-cannot-be-negative-got-symbo","errorCode":null,"errorMessage":"symbol_info_budget cannot be negative, got: {symbol_info_budget}","messagePattern":"symbol_info_budget cannot be negative, got: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/config/serena_config.py","lineNumber":615,"sourceCode":"        # Validate activation_command_timeout\n        activation_command_timeout_raw = data.get(\"activation_command_timeout\", 180.0)\n        try:\n            activation_command_timeout = float(activation_command_timeout_raw)\n        except (TypeError, ValueError) as e:\n            raise ValueError(f\"activation_command_timeout must be a number, got: {activation_command_timeout_raw}\") from e\n        if activation_command_timeout <= 0:\n            raise ValueError(f\"activation_command_timeout must be positive, got: {activation_command_timeout}\")\n\n        # Validate symbol_info_budget\n        symbol_info_budget_raw = data[\"symbol_info_budget\"]\n        symbol_info_budget = symbol_info_budget_raw\n        if symbol_info_budget is not None:\n            try:\n                symbol_info_budget = float(symbol_info_budget_raw)\n            except (TypeError, ValueError) as e:\n                raise ValueError(f\"symbol_info_budget must be a number or null, got: {symbol_info_budget_raw}\") from e\n            if symbol_info_budget < 0:\n                raise ValueError(f\"symbol_info_budget cannot be negative, got: {symbol_info_budget}\")\n\n        language_backend_value = data.get(\"language_backend\")\n        language_backend = LanguageBackend.from_str(language_backend_value) if language_backend_value else None\n\n        line_ending_value = data.get(\"line_ending\")\n        line_ending = LineEnding.from_str(line_ending_value) if line_ending_value else None\n\n        # gracefully handle user errors: incorrect use of None/empty where a list is required\n        ignored_paths = data[\"ignored_paths\"] or []\n        fixed_tools = data[\"fixed_tools\"] or []\n        excluded_tools = data[\"excluded_tools\"] or []\n        included_optional_tools = data[\"included_optional_tools\"] or []\n        additional_workspace_folders = data.get(\"ls_additional_workspace_folders\") or []\n\n        if \"base_modes\" in data and data[\"base_modes\"] is not None:\n            log.warning(\"The base_modes setting in project.yml is deprecated and will be ignored.\")\n\n        return cls(","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/config/serena_config.py#L597-L633","documentation":"SerenaConfig._from_dict validates the optional symbol_info_budget setting from serena_config.yml. The raw value is parsed to float, and a negative number is rejected because a budget of symbols sent to the LLM cannot be below zero. This is a defensive config-validation error raised at config-parse time.","triggerScenarios":"Calling SerenaConfig.load(), SerenaConfig.autogenerate(), or ProjectConfig._from_dict() when the symbol_info_budget key in serena_config.yml (or a dict passed to _from_dict) parses to a negative float, e.g. 'symbol_info_budget: -1'.","commonSituations":"Hand-editing serena_config.yml and typoing the value (e.g. '-1' as a placeholder, or a locale-style decimal like '-0,5' misinterpreted); test fixtures passing dicts with negative budgets; pasting config from an old version where the field meant something else.","solutions":["Open serena_config.yml and set symbol_info_budget to a non-negative number (e.g. 5000) or remove/null the key to use the default.","If building a dict programmatically, clamp or validate the value: max(0, value) before calling _from_dict.","Check for locale/formatted strings that parse as negative after float() conversion."],"exampleFix":"// before (serena_config.yml)\nsymbol_info_budget: -1\n// after\nsymbol_info_budget: 5000","handlingStrategy":"validation","validationCode":"def ensure_valid_budget(cfg: dict) -> None:\n    raw = cfg.get('symbol_info_budget')\n    if raw is not None:\n        v = float(raw)\n        if v < 0:\n            raise ValueError(f'symbol_info_budget must be >= 0, got {v}')","typeGuard":"def has_valid_budget(cfg: dict) -> bool:\n    raw = cfg.get('symbol_info_budget')\n    return raw is None or (isinstance(raw, (int, float)) and not isinstance(raw, bool) and raw >= 0)","tryCatchPattern":"try:\n    config = SerenaConfig.load()\nexcept ValueError as e:\n    if 'symbol_info_budget' in str(e):\n        fix_budget_in_yml(); config = SerenaConfig.load()\n    else:\n        raise","preventionTips":["Never hand-write negative placeholder values in serena_config.yml","Validate the yml with a schema check before loading","Clamp numeric config values programmatically when generating configs"],"tags":["configuration","validation","python"],"backgroundTag":"config-value-validation-failed","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}