langchain-ai/deepagents · error · TypeError

Unsupported `ptc` config type. Use a list of tool names, lis

Error message

Unsupported `ptc` config type. Use a list of tool names, list of BaseTool instances, or disable PTC.

What it means

The `ptc` option accepts only `True`/`False`, a list of tool names, or a list of BaseTool instances (and list forms handled above); any other config type is rejected with TypeError so misconfiguration fails loudly instead of silently disabling PTC.

Source

Thrown at libs/partners/quickjs/langchain_quickjs/_ptc.py:116

        selected = [
            *explicit_tools,
            *[t for t in tools if t.name != self_tool_name and t.name in allow_names],
        ]
        deduped: list[BaseTool] = []
        seen_names: set[str] = set()
        for tool in selected:
            if tool.name in seen_names:
                continue
            seen_names.add(tool.name)
            deduped.append(tool)
        selected = deduped
        _raise_on_invalid_ptc_tools(selected)
        return selected
    msg = (
        "Unsupported `ptc` config type. "
        "Use a list of tool names, list of BaseTool instances, or disable PTC."
    )
    raise TypeError(msg)


def to_camel_case(name: str) -> str:
    """Convert `snake_case` / `kebab-case` → `camelCase`."""
    return _prompt.to_camel_case(name)


def is_valid_js_identifier(name: str) -> bool:
    """Return whether `name` is a valid JavaScript identifier."""
    return _prompt.is_valid_js_identifier(name)


def is_valid_ptc_tool_name(name: str) -> bool:
    """Return whether a tool can be exposed as `tools.<camelCaseName>`."""
    return _prompt.is_valid_ptc_tool_name(name)


def _raise_on_invalid_ptc_tools(tools: Sequence[BaseTool]) -> None:

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Wrap a single tool name in a list: `ptc=["websearch"]`
  2. Use `ptc=True` / `ptc=False` to enable/disable all tools
  3. Remove dict wrappers and supply a plain list of names or BaseTool instances

Example fix

# before
ptc="websearch"
# after
ptc=["websearch"]
Defensive patterns

Strategy: type-guard

Validate before calling

if not (isinstance(ptc, bool) or (isinstance(ptc, list) and all(isinstance(x, (str, BaseTool)) for x in ptc))):
    raise TypeError(f"invalid ptc config: {type(ptc).__name__}")

Type guard

def is_valid_ptc_config(ptc: object) -> TypeGuard[Union[bool, list]]:
    if isinstance(ptc, bool):
        return True
    return isinstance(ptc, list) and all(isinstance(x, (str, BaseTool)) for x in ptc)

Try / catch

try:
    agent = QuickjsAgent(ptc=ptc_config)
except TypeError as e:
    if "Unsupported `ptc`" in str(e):
        if isinstance(ptc_config, str):
            ptc_config = [ptc_config]
        agent = QuickjsAgent(ptc=ptc_config)
    else:
        raise

Prevention

When it happens

Trigger: Passing e.g. `ptc="websearch"`, `ptc={"include": [...]}`, `ptc=None`, or a set to the agent's `ptc` parameter, reaching `filter_tools_for_ptc`'s fallthrough.

Common situations: Passing a single tool name string instead of a one-element list; dict-style include/exclude configs modeled after other frameworks; YAML/JSON values deserialized to unexpected types.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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