langchain-ai/deepagents · error · RuntimeError

{field} contains a malformed '${{...}}' reference. Use '${VA

Error message

{field} contains a malformed '${{...}}' reference. Use '${VAR}' or '${VAR:-default}'.

What it means

`_interpolate_env` only accepts well-formed `${VAR}` or `${VAR:-default}` references. Any `${` in the raw value that does not match the reference regex (e.g. `${VAR-default}` with a single dash, `${my var}`, or an unterminated `${VAR`) is rejected with `RuntimeError` instead of being emitted verbatim, so a typo cannot inject garbage into a URL, command, or header.

Source

Thrown at libs/code/deepagents_code/mcp_config.py:83

            return resolved
        # `${VAR}` unset with no default: the only hard error.
        msg = (
            f"{field} references unset env var {name}. "
            f"Set {name} in the environment or provide a default."
        )
        raise RuntimeError(msg)

    # Reject any `${` that isn't the start of a well-formed reference. The
    # check is against the raw `value` (not the substituted result) so a
    # resolved value that happens to contain `${` never trips it.
    ref_spans = [match.span() for match in _ENV_REF_RE.finditer(value)]
    for brace in _ENV_BRACE_RE.finditer(value):
        if not any(start <= brace.start() < end for start, end in ref_spans):
            msg = (
                f"{field} contains a malformed '${{...}}' reference. "
                "Use '${VAR}' or '${VAR:-default}'."
            )
            raise RuntimeError(msg)

    return _ENV_REF_RE.sub(replace, value)


def _resolve_string(value: object, *, field: str) -> str:
    """Validate and interpolate one string field.

    Args:
        value: Raw field value.
        field: Fully qualified field path for error messages.

    Returns:
        The validated and interpolated string.

    Raises:
        TypeError: If the field value is not a string.
    """
    if not isinstance(value, str):

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Correct the reference to `${VAR}` or `${VAR:-default}` syntax (note the `:-`, not a single `-`).
  2. Close the `${` with a matching `}` and use only letters, digits, and underscores in the variable name.
  3. If a literal `${` is required, it is not supported — restructure the value (e.g. split via `args`) or set the value through env so it resolves before this check (a resolved value containing `${` is not rescanned).

Example fix

// before
{"args": ["--x=${FOO-BAR}"]}  # single dash: malformed
// after
{"args": ["--x=${FOO:-BAR}"]}
Defensive patterns

Strategy: validation

Validate before calling

import re
REF = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^{}]*))?\}")
def malformed_refs(value: str) -> list[str]:
    spans = [m.span() for m in REF.finditer(value)]
    return [value[m.start():] for m in re.finditer(r"\$\{", value)
            if not any(s <= m.start() < e for s, e in spans)]

Try / catch

try:
    resolved = resolve_mcp_server_env(server_name, server_config)
except RuntimeError as exc:
    if "malformed" in str(exc):
        field = str(exc).split(" contains")[0]
        raise SystemExit(f"Fix the ${{...}} syntax in {field}") from exc
    raise

Prevention

When it happens

Trigger: Calling `resolve_mcp_server_env` (via `_resolve_string` -> `_interpolate_env`) with a field value containing `${...}` that fails the `_ENV_REF_RE` pattern: missing `}`, invalid variable characters, wrong default separator (`-` instead of `:-`), or an empty name.

Common situations: Hand-editing config and typing `${VAR-default}` or forgetting the closing brace; intentionally wanting a literal `${` in a value (e.g. shell snippet in an arg) which the validator refuses; regex/JSON snippets pasted from docs that use `${}` placeholder syntax.

Understand the failure class

Related errors


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