langchain-ai/deepagents · error · ValueError

chunk limit must be positive

Error message

chunk limit must be positive

What it means

`chunk_text` splits outbound channel text into pieces no longer than `limit` characters and raises `ValueError` if `limit` is not positive (`< 1`). A non-positive limit would make the splitting loop meaningless (infinite loop / empty chunks), so it is rejected up front. Default callers pass the channel's `MAX_TEXT_CHARS`, so this fires mainly with custom limits.

Source

Thrown at libs/talon/deepagents_talon/channels/base.py:161

    return _BOLD_PATTERN.sub(lambda match: f"*{match.group(1) or match.group(2)}*", value)


def chunk_text(text: str, *, limit: int = MAX_TEXT_CHARS) -> list[str]:
    """Split outbound text into channel-sized chunks.

    Args:
        text: Text to split.
        limit: Maximum characters per returned chunk.

    Returns:
        Non-empty chunks no longer than `limit`.

    Raises:
        ValueError: If `limit` is not positive.
    """
    if limit < 1:
        msg = "chunk limit must be positive"
        raise ValueError(msg)

    chunks: list[str] = []
    remaining = text
    while len(remaining) > limit:
        split = _split_index(remaining, limit)
        chunk = remaining[:split].rstrip()
        chunks.append(chunk or remaining[:limit])
        remaining = remaining[split:].lstrip()
    if remaining:
        chunks.append(remaining)
    return chunks


def channel_exposure_from_env(
    env: Mapping[str, str],
    config: ChannelExposureEnv,
) -> ChannelExposure:
    """Build shared channel exposure policy from provider-specific env prefix.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass a positive `limit` (at least 1; practically the channel's real character cap).
  2. Fix the config/env value that produced 0 or negative — e.g. ensure the max-length env var parses to a positive integer.
  3. If a bot header consumes the budget, increase the channel max length so `max_len - len(header) >= 1`.
  4. Clamp before calling: `limit = max(1, configured_limit)`.
  5. Use the default (`chunk_text(text)`) which applies `MAX_TEXT_CHARS`.

Example fix

// before
chunks = chunk_text(text, limit=0)  # ValueError

// after
chunks = chunk_text(text, limit=max(1, configured_limit))
Defensive patterns

Strategy: validation

Validate before calling

def safe_chunk(text: str, limit: int) -> list[str]:
    return chunk_text(text, limit=max(1, limit))

Type guard

def is_valid_chunk_limit(limit: int) -> bool:
    return isinstance(limit, int) and limit >= 1

Try / catch

try:
    chunks = chunk_text(text, limit=limit)
except ValueError as e:
    log.error("invalid chunk limit %s: %s", limit, e)
    chunks = chunk_text(text)  # fall back to default MAX_TEXT_CHARS

Prevention

When it happens

Trigger: Calling `chunk_text(text, limit=0)`, `chunk_text(text, limit=-5)`, or invoking it through `send_message` / `_chunk_with_bot_header` with a channel or bot-header configuration whose effective limit computed to <= 0 (e.g. header length >= max message length leaving no budget).

Common situations: Custom channel implementations passing an uninitialized or misparsed limit env var; a max-message-length setting smaller than the bot header, driving the residual chunk limit to zero; tests probing boundary conditions.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/8095100ff82e29fb. Report an issue: GitHub.