oraios/serena · error · ValueError

Must be positive or the default (-1), got: {max_answer_chars

Error message

Must be positive or the default (-1), got: {max_answer_chars=}

What it means

_limit_length validates max_answer_chars before using it: it must be the sentinel default -1 or a positive integer. Any other value (0, negative numbers other than -1) is rejected with this ValueError.

Source

Thrown at src/serena/tools/tools_base.py:298

    def _limit_length(
        self,
        result: str,
        max_answer_chars: int,
        shortened_result_factories: list[Callable[[], str]] | None = None,
    ) -> str:
        """Limit the length of the result string, optionally trying progressively shorter versions.

        :param result: the full result string
        :param max_answer_chars: maximum allowed characters. -1 means use the default from config.
        :param shortened_result_factories: optional list of closures, each producing a progressively shorter
            version of the result. They are tried in order until one fits within ``max_answer_chars``.
        :return: the result string, potentially replaced by a shortened version
        """
        if max_answer_chars == -1:
            max_answer_chars = self.agent.serena_config.default_max_tool_answer_chars
        if max_answer_chars <= 0:
            raise ValueError(f"Must be positive or the default (-1), got: {max_answer_chars=}")
        if (n_chars := len(result)) > max_answer_chars:
            too_long_msg = (
                f"The answer is too long ({n_chars} characters). " + "You can adjust your query or raise the max_answer_chars parameter."
            )
            if shortened_result_factories is not None:
                # try each shortening closure in order;
                for make_shorter in shortened_result_factories:
                    shortened = make_shorter()
                    candidate = f"{too_long_msg}\n{shortened}"
                    if len(candidate) <= max_answer_chars:
                        return candidate
            result = too_long_msg
        return result

    def is_active(self) -> bool:
        return self.agent.tool_is_active(self.get_name())

    def is_readonly(self) -> bool:

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Pass -1 to use serena_config.default_max_tool_answer_chars
  2. Pass a positive integer, e.g. max_answer_chars=10000
  3. Fix the config/computation that produced the invalid value

Example fix

// before
listing_tool.apply(max_answer_chars=0)
// ValueError: Must be positive or the default (-1), got: max_answer_chars=0

// after
listing_tool.apply(max_answer_chars=-1)  # use config default
# or
listing_tool.apply(max_answer_chars=50000)
Defensive patterns

Strategy: validation

Validate before calling

def sane_limit(v: int, default: int) -> int:
    return default if v == -1 else (v if v > 0 else default)
result = tool.apply(max_answer_chars=sane_limit(requested, agent.serena_config.default_max_tool_answer_chars))

Type guard

def valid_limit(v: int) -> bool:
    return v == -1 or v > 0

Try / catch

try:
    result = tool.apply(max_answer_chars=limit)
except ValueError as e:
    if 'Must be positive' in str(e):
        result = tool.apply(max_answer_chars=-1)
    else:
        raise

Prevention

When it happens

Trigger: Calling a listing tool with max_answer_chars=0 or a negative value like -5; programmatically computing a limit that rounds down to 0.

Common situations: Config default mis-set to 0; caller passes -1 meaning 'auto' in one tool but 0 in another; dynamic limits computed from empty values (e.g. int(None or 0)).

Related errors


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