Skip to content

GCS skill loaders ignore a skill.md manifest that the local and zip loaders accept #7842

Description

@adityasingh2400

🔴 Required Information

Describe the Bug:
A skill whose manifest is named skill.md loads from a local directory or a zip archive but is invisible when stored in GCS. _parse_skill_md, _list_skills_in_dir and the zip loader in skills/_utils.py all accept SKILL.md or skill.md. _list_skills_in_gcs_dir and _load_skill_from_gcs_dir only look for SKILL.md. Moving a skill that works locally into a bucket therefore makes it disappear from the listing, and loading it raises FileNotFoundError. The async wrappers call the same functions and behave the same way.

Steps to Reproduce:

  1. Upload a skill directory with gs://my-bucket/skills/my-skill/skill.md (valid frontmatter, name: my-skill).
  2. _list_skills_in_gcs_dir("my-bucket", "skills/").
  3. _load_skill_from_gcs_dir("my-bucket", "my-skill", skills_base_path="skills/").

Expected Behavior:
The skill is listed and loads, as it does from a local directory.

Observed Behavior:
The listing is {}, and loading raises FileNotFoundError: SKILL.md not found at gs://my-bucket/skills/my-skill/SKILL.md.

Environment Details:

  • ADK Library Version (pip show google-adk): 2.13.0 (also on main at 75fb788)
  • Desktop OS: macOS
  • Python Version (python -V): 3.11.16

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A (skill loading)

🟡 Optional Information

Additional Context:
I verified this with the mocked google.cloud.storage client the existing GCS skill tests use; I don't have a bucket for a live run.

How often has this issue occurred?:

  • Always (100%), for GCS skills whose manifest is skill.md

Activity

  1. surajksharma07 commented on Oct 30, 2026

    @surajksharma07
    Collaborator

    Thanks @adityasingh2400, Reproduced this on 2.13.0 with a mocked storage client: the local loader picks up skill.md but the GCS list comes back empty and the load throws FileNotFoundError.

    For now renaming the manifest to SKILL.md in the bucket gets around it. If that’s not an option, wrapping the bucket so it falls back to skill.md when SKILL.md is missing worked for me on both list and load. Could you check if one of these works on your side?

    Before #7843 goes for review please give it a good round of testing too, especially that SKILL.md is still tried first and existing skills load the same as before.

  2. adityasingh2400 commented on Oct 31, 2026

    @adityasingh2400
    ContributorAuthor

    Thanks for reproducing it. Renaming to SKILL.md does work around it, but the local and zip loaders already accept skill.md, so #7843 makes the GCS loader match them rather than asking people to rename their buckets.

    On ordering: _find_gcs_skill_manifest checks SKILL.md first and only looks up skill.md when it is missing. I just pushed a test for the case where both files exist (test__load_skill_from_gcs_dir_prefers_uppercase_manifest): the loader reads SKILL.md and never looks up skill.md. That test passes on main too, so existing skills load exactly as before. The existing SKILL.md tests pass unmodified, and tests/unittests/skills passes (134 tests).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

tools[Component] This issue is related to tools

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions