microsoft/aspire · error · InvalidOperationException

Skill ' ' does not define installable files.

Error message

Skill '{skill.Name}' does not define installable files.

What it means

GetSkillFilesAsync ends with a terminal throw for skills that match none of the supported source kinds (e.g. not an Aspire skills bundle or another file-providing source) yet carry no installable files. The library throws because it cannot produce the file set the agent-init install step requires for this skill.

Solutions

  1. Add installable file definitions to the skill so it maps to a supported file-providing source kind
  2. Exclude the file-less skill from the file-install path (it may only need registration, not file installation)
  3. Verify the skill's manifest declares the correct SourceKind

Example fix

// before
var files = await GetSkillFilesAsync(skill, aspireSkillsBundle, cancellationToken);
// after
if (skill.SourceKind is not (SkillSourceKind.AspireSkillsBundle or SkillSourceKind.LocalFiles))
{
    continue; // file-less skill: register without installing files
}
var files = await GetSkillFilesAsync(skill, aspireSkillsBundle, cancellationToken);
Defensive patterns

Strategy: validation

Validate before calling

if (!skillHasInstallableFiles(skill))
{
    continue; // file-less skill: skip the file-install path
}

Type guard

var hasFiles = skill.SourceKind is SkillSourceKind.AspireSkillsBundle or SkillSourceKind.LocalFiles;

Try / catch

try
{
    files = await GetSkillFilesAsync(skill, bundle, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("does not define installable files"))
{
    logger.LogInformation("Skill {Skill} has no files; registering only", skill.Name);
}

Prevention

When it happens

Trigger: Invoking GetSkillFilesAsync with a skill whose SourceKind is a kind that does not implement GetSkillFilesAsync and that defines no installable file entries — e.g. a metadata-only or inline/documented skill with no files.

Common situations: A custom or user-defined skill in the agent-init skill configuration that only provides instructions (no files), but is processed by the file-install path; misconfigured skill manifest missing its file definitions.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/d2d52435c45ce318. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Cli/Commands/AgentInitCommand.cs:771

    private static async Task<IReadOnlyList<SkillAssetFile>> GetSkillFilesAsync(SkillDefinition skill, AspireSkillsBundle? aspireSkillsBundle, CancellationToken cancellationToken)
    {
        if (skill.SkillContent is not null)
        {
            return [new SkillAssetFile("SKILL.md", skill.SkillContent)];
        }

        if (skill.SourceKind is SkillSourceKind.AspireSkillsBundle)
        {
            if (aspireSkillsBundle is null)
            {
                throw new InvalidOperationException($"Aspire skills bundle was not resolved for skill '{skill.Name}'.");
            }

            return await aspireSkillsBundle.GetSkillFilesAsync(skill, cancellationToken);
        }

        throw new InvalidOperationException($"Skill '{skill.Name}' does not define installable files.");
    }

    private sealed record InstalledSkillSummaryItem(string SkillName, string DisplayLocation);

    private readonly record struct SkillInstallResult(bool Succeeded, InstalledSkillSummaryItem? UpdatedSkill);
}

internal readonly record struct AgentInitExecutionResult(
    int ExitCode,
    IReadOnlyList<SkillLocation> SelectedLocations,
    IReadOnlyList<SkillDefinition> SelectedSkills);

View on GitHub (pinned to 25830f84bd)