github/spec-kit · error · ValueError
No extension.yml found in {source_path}
Error message
No extension.yml found in {source_path} What it means
A local directory passed to `specify init --extension ./path` must contain a top-level extension.yml. If the directory exists but that manifest is absent, Spec Kit raises ValueError and fails that extension step before installing anything.
Source
Thrown at src/specify_cli/commands/init.py:124
# --- URL ---
parsed = urlparse(ext_spec)
if parsed.scheme in ("http", "https"):
try:
manifest = install_extension_from_url(
manager, project_path, ext_spec, speckit_version
)
except ExtensionError as exc:
raise ValueError(str(exc)) from exc
return f"{manifest.name} v{manifest.version} installed"
# --- Local path ---
if ext_spec.startswith(("./", "../", "/", "~/", ".\\", "..\\")) or Path(ext_spec).is_absolute():
source_path = Path(ext_spec).expanduser().resolve()
if not source_path.exists():
raise ValueError(f"Directory not found: {source_path}")
if not (source_path / "extension.yml").exists():
raise ValueError(f"No extension.yml found in {source_path}")
manifest = manager.install_from_directory(source_path, speckit_version)
return f"{manifest.name} v{manifest.version} installed"
# --- Bundled extension name or catalog ID ---
bundled_path = _locate_bundled_extension(ext_spec)
if bundled_path is not None:
if manager.registry.is_installed(ext_spec):
return "already installed"
manifest = manager.install_from_directory(bundled_path, speckit_version)
return f"{manifest.name} v{manifest.version} installed"
# Fall back to catalog
catalog = ExtensionCatalog(project_path)
ext_info, catalog_error = _resolve_catalog_extension(ext_spec, catalog, "add")
if catalog_error:
raise ValueError(f"Could not query extension catalog: {catalog_error}")
if not ext_info:
raise ValueError(f"Extension '{ext_spec}' not found in bundled extensions or catalog")View on GitHub (pinned to bf88c9f9a8)
Solutions
- List the directory shown in the error and confirm whether the manifest is missing, nested, or differently named.
- Move/rename the manifest so `<source_path>/extension.yml` exists exactly.
- Point --extension at the directory that directly contains extension.yml.
- Create a minimal valid extension.yml if this is a new extension.
Example fix
# before my-ext/ extension.yaml # after my-ext/ extension.yml
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def extension_dir_has_manifest(path: Path) -> bool:
return path.is_dir() and (path / "extension.yml").is_file() Try / catch
try:
_install_extension_during_init(project_path, ext_spec, version)
except ValueError as exc:
if str(exc).startswith("No extension.yml"):
show_expected_layout(ext_spec)
else:
raise Prevention
- Use exactly extension.yml at the source directory root.
- Add a repository lint that rejects extension.yaml or nested manifests.
- Point at the directory containing the manifest, not its parent.
When it happens
Trigger: The resolved source directory exists but contains extension.yaml, manifest.yml, or extension.yml nested in a subdirectory instead of a root-level extension.yml.
Common situations: The file was named with the .yaml suffix, the user pointed at the repository root while the extension lives in a subdirectory, or the manifest was never created.
Related errors
- Directory not found: {source_path}
- Could not read manifest {path}: {e}
- No bundle.yml found in '{bundle_dir}'.
- No bundle.yml found in '{candidate}'.
- No bundle.yml found at '{target}'.
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/f8d388dcdb820ee2.
Report an issue: GitHub.