langchain-ai/deepagents · error · ValueError
PTC tool name {tool.name!r} cannot be exposed as JavaScript
Error message
PTC tool name {tool.name!r} cannot be exposed as JavaScript identifier {camel!r}. Tool names must map to `/^[A-Za-z_$][A-Za-z0-9_$]*$/`. What it means
Each PTC tool is exposed in JavaScript as a camelCase identifier; a tool whose name cannot be converted to a valid JS identifier (must match `/^[A-Za-z_$][A-Za-z0-9_$]*$/`) would generate broken/unreachable JS bindings, so it is rejected with ValueError during PTC tool validation or prompt rendering.
Source
Thrown at libs/partners/quickjs/langchain_quickjs/_ptc.py:144
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:
for tool in tools:
camel = to_camel_case(tool.name)
if is_valid_js_identifier(camel):
continue
msg = (
f"PTC tool name {tool.name!r} cannot be exposed as JavaScript "
f"identifier {camel!r}. Tool names must map to "
"`/^[A-Za-z_$][A-Za-z0-9_$]*$/`."
)
raise ValueError(msg)
def render_ptc_prompt(tools: Sequence[BaseTool], *, tool_name: str = "eval") -> str:
"""Build the `tools` namespace section of the system prompt."""
if not tools:
return ""
_raise_on_invalid_ptc_tools(tools)
return _prompt.render_ptc_prompt(tools, tool_name=tool_name)
View on GitHub (pinned to a1af029e6e)
Solutions
- Rename the tool so it is alphanumeric snake_case starting with a letter (e.g. `web_search` instead of `/search/web`)
- Set an explicit JS-safe tool name via the tool's name/alias when registering
- Sanitize third-party tool names before passing them into a PTC-enabled agent
Example fix
# before @tool def 3d-render(query: str) -> str: ... # after @tool def render_3d(query: str) -> str: ...
Defensive patterns
Strategy: validation
Validate before calling
import re
_JS_IDENT = re.compile(r"^[A-Za-z_$][A-Za-z0-9_$]*$")
for t in tools:
camel = to_camel_case(t.name)
if not _JS_IDENT.match(camel):
raise ValueError(f"tool {t.name!r} -> {camel!r} is not a valid JS identifier") Type guard
def is_js_safe_tool_name(name: str) -> bool:
camel = to_camel_case(name)
return bool(re.fullmatch(r"[A-Za-z_$][A-Za-z0-9_$]*", camel)) Try / catch
try:
selected = filter_tools_for_ptc(tools, config)
except ValueError as e:
if "JavaScript identifier" in str(e):
tools = [rename_tool(t, sanitize_js_name(t.name)) for t in tools]
selected = filter_tools_for_ptc(tools, config)
else:
raise Prevention
- Name tools with lowercase snake_case identifiers starting with a letter
- Sanitize names derived from routes, paths, or user input before tool registration
- Run render_ptc_prompt on all PTC tool sets in tests to catch naming issues early
When it happens
Trigger: Calling `filter_tools_for_ptc` or `render_ptc_prompt` with a tool whose name, after camelCase conversion, starts with a digit, contains characters like `-`, `.`, `/`, or unicode, or is empty.
Common situations: Tool names derived from HTTP routes or file paths (`/search/web`, `my-tool.v2`); names starting with digits (`3d_render`); dynamically generated tool names from user input.
Related errors
- The subagent `task` tool cannot be exposed via `ptc`. It is
- ptc list entries must be str or BaseTool
- Invalid agent name: {agent_name!r} is reserved for dcode's o
- trusted_ask_user_tool must be named ask_user
- trusted_compaction_tool must be named compact_conversation
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/56db0134ba9912a6.
Report an issue: GitHub.