langchain-ai/deepagents · error · ValueError

`max_ptc_calls` must be >= 1 or None

Error message

`max_ptc_calls` must be >= 1 or None

What it means

The REPL middleware validates at construction that `max_ptc_calls` is either `None` (unlimited/default budget behavior) or an integer >= 1, since a PTC call budget of zero or negative makes no sense. Invalid values raise `ValueError` immediately in `__init__`.

Source

Thrown at libs/partners/quickjs/langchain_quickjs/middleware.py:260

        self,
        *,
        memory_limit: int = _DEFAULT_MEMORY_LIMIT,
        timeout: float = _DEFAULT_TIMEOUT,
        max_ptc_calls: int | None = _DEFAULT_MAX_PTC_CALLS,
        tool_name: str = _DEFAULT_TOOL_NAME,
        max_result_chars: int = _DEFAULT_MAX_RESULT_CHARS,
        capture_console: bool = True,
        subagents: bool = True,
        ptc: PTCOption | None = None,
        mode: PersistenceMode | None = None,
        max_snapshot_bytes: int | None = None,
        snapshot_signing_key: str | bytes | None = None,
    ) -> None:
        """Initialize REPL middleware state and build the exposed eval tool."""
        super().__init__()
        if max_ptc_calls is not None and max_ptc_calls < 1:
            msg = "`max_ptc_calls` must be >= 1 or None"
            raise ValueError(msg)
        if max_snapshot_bytes is not None and max_snapshot_bytes < 1:
            msg = "`max_snapshot_bytes` must be >= 1 or None"
            raise ValueError(msg)
        self._memory_limit = memory_limit
        self._timeout = timeout
        self._max_ptc_calls = max_ptc_calls
        self._tool_name = tool_name
        self._max_result_chars = max_result_chars
        self._capture_console = capture_console
        self._subagents = subagents
        self._ptc = ptc
        self._mode = _resolve_mode(mode=mode)
        self._max_snapshot_bytes = (
            memory_limit if max_snapshot_bytes is None else max_snapshot_bytes
        )
        self._snapshot_signing_key = (
            normalize_signing_key(snapshot_signing_key)
            if snapshot_signing_key is not None

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Pass `max_ptc_calls=None` to use the default/unlimited budget behavior, not 0.
  2. Set a positive integer budget (>= 1) if you want to cap PTC calls.
  3. Sanitize env/config input: coerce missing values to None rather than 0.

Example fix

// before
QuickJsMiddleware(max_ptc_calls=int(os.environ.get("MAX_PTC", 0)))  # 0 -> ValueError

// after
raw = os.environ.get("MAX_PTC")
QuickJsMiddleware(max_ptc_calls=int(raw) if raw else None)
Defensive patterns

Strategy: validation

Validate before calling

if max_ptc_calls is not None and max_ptc_calls < 1:
    raise ValueError("max_ptc_calls must be >= 1 or None")

Type guard

def is_valid_budget(v) -> bool:
    return v is None or (isinstance(v, int) and not isinstance(v, bool) and v >= 1)

Try / catch

try:
    mw = QuickJsMiddleware(max_ptc_calls=max_ptc_calls)
except ValueError as e:
    if "max_ptc_calls" in str(e):
        mw = QuickJsMiddleware(max_ptc_calls=None)

Prevention

When it happens

Trigger: `QuickJsMiddleware(max_ptc_calls=0)`, a negative number, or a value computed from config/env that resolves to 0 (e.g. `int(os.environ.get("MAX_PTC", 0))`).

Common situations: Misreading the option as 'disable PTC' and setting 0 instead of None; an env var defaulting to 0; a config file with `max_ptc_calls: 0`.

Understand the failure class

Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.

Related errors


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