langchain-ai/deepagents · error · ValueError

system_prompt missing required format slot(s): {', '.join(mi

Error message

system_prompt missing required format slot(s): {', '.join(missing)}

What it means

A custom `system_prompt` for SkillsMiddleware must contain the three format slots {skills_locations}, {skills_load_warnings}, and {skills_list}, because the middleware interpolates discovered skill paths, load warnings, and the skill listing into the prompt at runtime. A prompt missing any slot would silently drop that information, so it's rejected with ValueError listing the missing slots.

Source

Thrown at libs/deepagents/deepagents/middleware/skills.py:846

                to skip appending entirely (skills are still loaded into
                `state["skills_metadata"]`).

        Raises:
            TypeError: If a tuple entry in `sources` is not exactly a
                `(str, str)` pair, or if `system_prompt` is not `str` or
                `None`.
            ValueError: If `system_prompt` is a string missing any of the
                required format slots.
        """
        if system_prompt is not None:
            if not isinstance(system_prompt, str):
                msg = f"system_prompt must be str or None, got {type(system_prompt).__name__}"
                raise TypeError(msg)
            required = ("{skills_locations}", "{skills_load_warnings}", "{skills_list}")
            missing = [slot for slot in required if slot not in system_prompt]
            if missing:
                msg = f"system_prompt missing required format slot(s): {', '.join(missing)}"
                raise ValueError(msg)
        self._backend = backend
        # `self.sources` remains paths-only (`list[str]`) to preserve
        # backwards-compat for callers that inspect it directly; label
        # information is mirrored on `self.source_labels` at the same index.
        self.sources: list[str] = [_source_path(s) for s in sources]
        self.source_labels: list[str] = [_derive_source_label(s) for s in sources]
        self.system_prompt_template = system_prompt

    def _format_skills_locations(self) -> str:
        """Format skills locations for display in system prompt."""
        locations = []
        last = len(self.sources) - 1

        for i, (source_path, label) in enumerate(zip(self.sources, self.source_labels, strict=True)):
            suffix = " (higher priority)" if i == last else ""
            locations.append(f"**{label} Skills**: `{source_path}`{suffix}")

        return "\n".join(locations)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Add all three slots: {skills_locations}, {skills_load_warnings}, {skills_list}.
  2. Start from the library's default prompt and edit around it rather than rewriting.
  3. Read the ValueError message — it names exactly which slot(s) are missing.
  4. If you don't need customization, pass system_prompt=None to use the default.

Example fix

// before
system_prompt="You can load skills."
// after
system_prompt="You can load skills.\nLocations: {skills_locations}\nWarnings: {skills_load_warnings}\n{skills_list}"
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED = ("{skills_locations}", "{skills_load_warnings}", "{skills_list}")
missing = [s for s in REQUIRED if s not in system_prompt]
if missing:
    raise ValueError(f"system_prompt missing: {missing}")

Type guard

def prompt_has_slots(p: str) -> bool:
    return all(slot in p for slot in ("{skills_locations}", "{skills_load_warnings}", "{skills_list}"))

Try / catch

try:
    mw = SkillsMiddleware(backend=b, system_prompt=custom_prompt)
except ValueError as e:
    if "missing required format slot" in str(e):
        mw = SkillsMiddleware(backend=b)  # fall back to default prompt
    else:
        raise

Prevention

When it happens

Trigger: SkillsMiddleware(backend=..., system_prompt="You have skills available.") — no slots; a partially customized prompt containing only {skills_list}.

Common situations: Trimming the default prompt for brevity and cutting slots; rewriting the prompt from scratch; copying a prompt from an older version whose slot names changed.

Related errors


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