{"record":{"id":"2b33843b90ee8d5e","repo":"larksuite/cli","slug":"host-embedded-skill-content-is-invalid","errorCode":null,"errorMessage":"host embedded skill content is invalid","messagePattern":"host embedded skill content is invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillpolicy/resolver.go","lineNumber":44,"sourceCode":"}\n\n// ErrMultipleSkillsOverlays reports that more than one plugin tried to\n// customize skill content. Mirrors cmdpolicy.ErrMultipleRestricts: only\n// one owner is allowed so independent plugins cannot silently overwrite\n// each other's skill tree.\nvar ErrMultipleSkillsOverlays = errors.New(\"multiple plugins customized skills; only one plugin may own skill content\")\n\n// ErrNoBaseSkillContent reports that Allow or Remove was requested against an\n// empty base tree. This most often means an external wrapper main omitted\n// cmd.SetEmbeddedSkillContent; exposing a sentinel lets the command layer give\n// the integrator that specific recovery action instead of blaming a skill-name\n// typo.\nvar ErrNoBaseSkillContent = errors.New(\"build embeds no base skill content\")\n\n// ErrInvalidHostBase reports that the wrapper-provided base skill tree is\n// malformed. It is distinct from a plugin's replacement Base so diagnostics\n// can direct the integrator to the correct owner.\nvar ErrInvalidHostBase = errors.New(\"host embedded skill content is invalid\")\n\n// ErrUnsatisfiedSkillDependency reports that a skill retained by the final\n// composed manifest declares another skill that the manifest does not retain.\n// The resolver never widens Allow or overrides Remove to repair this: an\n// incomplete distribution is a build-integrity error.\nvar ErrUnsatisfiedSkillDependency = errors.New(\"composed skill tree has an unsatisfied required skill\")\n\n// Resolution is the build-local result of composing embedded skill assets.\n// Content serves `skills list`/`read`; References projects canonical\n// CLI-authored pointers onto that same tree.\ntype Resolution struct {\n\tContent    fs.FS\n\tReferences *skillref.Resolver\n}\n\n// resolveContent is a test convenience over the production resolution path.\nfunc resolveContent(base fs.FS, specs []PluginSkill) (fs.FS, error) {\n\tresolved, err := ResolveWithReferences(base, specs)","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillpolicy/resolver.go#L26-L62","documentation":"ErrInvalidHostBase reports that the wrapper-provided base skill tree passed to cmd.SetEmbeddedSkillContent is malformed — bad frontmatter, invalid skill names, or similar. It is deliberately distinct from a plugin's replacement Base so diagnostics can direct the integrator (the host) to fix their content rather than suspecting a plugin. ResolveWithReferences returns it on fail-closed validation paths, and the command layer attaches a hint pointing at SetEmbeddedSkillContent.","triggerScenarios":"Resolution fails while validating the host-embedded base tree: unclosed frontmatter in a SKILL.md, or an invalid required-skill name — the fail-closed tests (TestResolve_UnclosedFrontmatterFailsClosed, TestResolve_InvalidRequiredSkillNameFailsClosed) exercise these paths.","commonSituations":"Hand-edited embedded SKILL.md files with broken YAML frontmatter delimiters; renamed skills leaving stale references; wrapper builds embedding content generated by an older or misconfigured tool.","solutions":["Fix the malformed content passed to cmd.SetEmbeddedSkillContent — check frontmatter delimiters and skill names.","Validate each base skill file's frontmatter (--- delimiters, valid name fields) before building the embed FS.","Rebuild and re-run resolution; the fail-closed behavior ensures nothing partially loads until the base tree is valid."],"exampleFix":"// before: embedded SKILL.md with unclosed frontmatter\n---\nname: my-skill\ndescription: ...\n# content\n// after\n---\nname: my-skill\ndescription: ...\n---\n# content","handlingStrategy":"try-catch","validationCode":"// sanity-check each embedded SKILL.md's frontmatter before embedding:\nfor _, f := range skillFiles {\n    if !hasClosedFrontmatter(f) { return fmt.Errorf(\"unclosed frontmatter in %s\", f) }\n}","typeGuard":"if errors.Is(err, skillpolicy.ErrInvalidHostBase) {\n    // host content is malformed; do not blame plugins\n}","tryCatchPattern":"if err := execute(); err != nil {\n    if errors.Is(err, skillpolicy.ErrInvalidHostBase) {\n        // fix the content passed to cmd.SetEmbeddedSkillContent\n    }\n}","preventionTips":["Lint embedded SKILL.md frontmatter (delimiters, name fields) in CI before embedding.","Distinguish host-base errors from plugin replacement errors when triaging (the sentinel encodes the owner).","Regenerate embedded content with the current tooling after skill renames."],"tags":["go","skills","embed","frontmatter","build-integrity"],"backgroundTag":"invalid-embedded-content","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}