Skip to content

GCPSkillRegistry.search_skills crashes on the first catalog entry that fails Frontmatter validation #6838

Description

@doublenum

🔴 Required Information

Describe the Bug:
GCPSkillRegistry.search_skills() constructs a models.Frontmatter for every hit returned by the Agent Registry skills:search endpoint with no per-item error handling. Frontmatter.name is validated against _SNAKE_OR_KEBAB_NAME_PATTERN (only a-z, 0-9, -, _), but real first-party catalog entries carry names outside that pattern — e.g. cloud.google.com-agent-platform-eval-flywheel (dots). The first such entry raises a pydantic ValidationError and sinks the entire search call, so search_skills is unusable against any catalog containing one non-conforming entry — including entries the caller never asked about.

google/adk/integrations/skill_registry/gcp_skill_registry.py, search_skills() (2.7.1, ~line 214):

results = []
for s in response_data.get("skills", []):
  results.append(
      models.Frontmatter(
          name=s.get("name", "").split("/")[-1],   # <- one bad name raises, whole call dies
          description=s.get("description", "") or "",
      )
  )
return results

Steps to Reproduce:

  1. Install google-adk==2.7.1.
  2. Point GCPSkillRegistry at an Agent Registry project/location whose catalog contains at least one skill whose last path segment does not match _SNAKE_OR_KEBAB_NAME_PATTERN (the public first-party entry cloud.google.com-agent-platform-eval-flywheel reproduces this).
  3. await registry.search_skills(query="anything").
  4. pydantic ValidationError for Frontmatter.name; no results are returned at all.

Expected Behavior:
A catalog entry that fails client-side frontmatter validation is skipped (optionally logged), and the remaining valid hits are returned. One malformed/non-conforming entry — which the searching agent has no control over — should not make skill discovery unusable for the whole catalog.

Observed Behavior:
pydantic_core._pydantic_core.ValidationError: 1 validation error for Frontmattername string does not match the snake/kebab pattern — raised out of search_skills(); the whole call fails.

Environment Details:

  • ADK Library Version (pip show google-adk): 2.7.1
  • Desktop OS: Linux
  • Python Version (python -V): 3.12

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A (client-side registry parsing; no model involved)

Suggested fix

Wrap the per-item Frontmatter construction in try/except, debug-log and skip the failing entry. We have been running exactly that as a client-side monkey-patch in production and it restores discovery against the real catalog:

for s in response_data.get("skills", []):
  try:
    results.append(
        models.Frontmatter(
            name=s.get("name", "").split("/")[-1],
            description=s.get("description", "") or "",
        )
    )
  except Exception:
    logger.debug("search_skills: skipped result failing frontmatter validation: %r", s.get("name"))

Happy to send a PR if that direction is acceptable.

Related context: since 2.7 get_skill() also validates names against the same pattern before building the resource URL (11101ac / #6805), so non-conforming catalog entries are now unloadable by design — which is fine, but they still appear in search responses, so search_skills needs to tolerate them rather than crash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions