What happened?
POST /api/skills/import (.md/.zip/.skill upload) silently ignores the user-invocable and
disable-model-invocation SKILL.md frontmatter fields. The created skill always lands on the schema
defaults (userInvocable: true, disableModelInvocation: false) regardless of what the uploaded
file specifies — with no error, warning, or partial-import notice. The request returns 201 as if
the import fully succeeded.
Expected: all three invocation-mode frontmatter fields (always-apply, user-invocable,
disable-model-invocation) are honored on import, matching what POST/PATCH /api/skills already
does when the flags are passed via an explicit frontmatter object.
Actual: only always-apply is honored. user-invocable and disable-model-invocation are
silently reset to their defaults.
Root cause: packages/api/src/skills/import.ts's parseFrontmatter() is scoped to extract only
name, description, and always-apply/alwaysApply — it never reads user-invocable or
disable-model-invocation, so those keys are dropped before the skill is created.
Why this matters beyond a parsing gap: the skill create/edit UI has no controls for any of the
three invocation-mode flags either (see companion enhancement issue #14209 ). That means for anyone not
calling the API directly with a raw frontmatter object (or editing the DB), there is currently no
supported way to restrict a skill's invocation channels at all — every UI-created or imported skill
ends up simultaneously $-invocable by any user and auto-invocable by the model, regardless of
author intent. That's a meaningful gap for anyone distributing a curated skill library where some
skills are meant to be manual-only or model-only.
Version Information
LibreChat version: v0.8.7
Commit: 9e74cc0
Branch: v0.8.7
Build date: 2026-06-24 19:41:25 UTC
User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
Steps to Reproduce
- Author a SKILL.md with frontmatter that diverges from the schema defaults:
---
name: test-skill
description: test
always-apply: true
user-invocable: false
disable-model-invocation: true
---
Test body.
POST /api/skills/import with this file as multipart form-data, field name file.
- Inspect the response / the created skill document.
Expected: alwaysApply:true, userInvocable:false, disableModelInvocation:true.
Actual: alwaysApply:true (correct) but userInvocable:true and disableModelInvocation:false
(both silently reverted to defaults).
What browsers are you seeing the problem on?
No response
Relevant log output
The evidence is the request/response pair itself:
POST /api/skills/import (multipart, field "file" = SKILL.md above)
→ HTTP 201
{
"name": "test-skill",
"alwaysApply": true, // correct — matches the file
"userInvocable": true, // WRONG — file said false
"disableModelInvocation": false, // WRONG — file said true
...
}
Confirmed against `packages/data-schemas/src/schema/skill.ts` that `true`/`false` are exactly the
schema defaults for these two fields — i.e. the import path silently falls through to "unset."
Screenshots
No response
Code of Conduct
What happened?
POST /api/skills/import(.md/.zip/.skillupload) silently ignores theuser-invocableanddisable-model-invocationSKILL.md frontmatter fields. The created skill always lands on the schemadefaults (
userInvocable: true,disableModelInvocation: false) regardless of what the uploadedfile specifies — with no error, warning, or partial-import notice. The request returns
201as ifthe import fully succeeded.
Expected: all three invocation-mode frontmatter fields (
always-apply,user-invocable,disable-model-invocation) are honored on import, matching whatPOST/PATCH /api/skillsalreadydoes when the flags are passed via an explicit
frontmatterobject.Actual: only
always-applyis honored.user-invocableanddisable-model-invocationaresilently reset to their defaults.
Root cause:
packages/api/src/skills/import.ts'sparseFrontmatter()is scoped to extract onlyname,description, andalways-apply/alwaysApply— it never readsuser-invocableordisable-model-invocation, so those keys are dropped before the skill is created.Why this matters beyond a parsing gap: the skill create/edit UI has no controls for any of the
three invocation-mode flags either (see companion enhancement issue #14209 ). That means for anyone not
calling the API directly with a raw
frontmatterobject (or editing the DB), there is currently nosupported way to restrict a skill's invocation channels at all — every UI-created or imported skill
ends up simultaneously
$-invocable by any user and auto-invocable by the model, regardless ofauthor intent. That's a meaningful gap for anyone distributing a curated skill library where some
skills are meant to be manual-only or model-only.
Version Information
LibreChat version: v0.8.7
Commit: 9e74cc0
Branch: v0.8.7
Build date: 2026-06-24 19:41:25 UTC
User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
Steps to Reproduce
POST /api/skills/importwith this file as multipart form-data, field namefile.Expected:
alwaysApply:true,userInvocable:false,disableModelInvocation:true.Actual:
alwaysApply:true(correct) butuserInvocable:trueanddisableModelInvocation:false(both silently reverted to defaults).
What browsers are you seeing the problem on?
No response
Relevant log output
Screenshots
No response
Code of Conduct