grok-plugin-json-valid¶
.grok-plugin/plugin.json must be valid JSON with a name Grok's loader accepts
| Severity | error (auto) |
| Autofix | - |
| Since | v0.20.0 |
| Repo Types | grok-marketplace, grok-plugin |
| Category | Grok Build |
Why¶
.grok-plugin/plugin.json is the manifest Grok Build reads to register a
plugin package and discover the components it provides.
While a manifest is optional — plugins containing standard skills/,
agents/, or hooks/hooks.json load conventions automatically — including
a well-formed plugin.json enables you to specify custom paths, component
declarations, metadata, and versioning.
Validating plugin.json ensures your plugin package installs smoothly and
registers all intended components:
- If a manifest contains invalid JSON or lacks a valid name, Grok may skip the plugin directory during installation.
- Declared component paths (
skills,commands,agents,hooks,mcpServers) should resolve to actual files or directories within the plugin so all features are available at runtime.
Grok resolves plugin manifests by checking plugin.json,
.grok-plugin/plugin.json, and .claude-plugin/plugin.json in order. Skillsaw
reports on whichever manifest file Grok discovers.
Severity¶
Findings distinguish between structural errors that prevent installation and path advisories:
Errors — issues that prevent Grok from registering the plugin:
- Invalid JSON syntax, a leading UTF-8 BOM, or non-finite number tokens
(
NaN,Infinity,-Infinity). - Duplicate recognized manifest fields or recognized fields inside
author. - Known fields with values the typed manifest decoder rejects.
- Manifest is not a JSON object.
- Missing, empty, or non-string
name. - A
namethat does not match Grok's plugin naming requirements (1-64 characters, lowercase alphanumeric and hyphens, no leading or trailing hyphen).
The typed fields use these shapes:
| Fields | Accepted values |
|---|---|
version, description, homepage, repository, license |
String, null, or omitted |
author |
Object, null, or omitted; its name, email, url are optional strings |
keywords |
Array of strings; omission defaults to an empty array, but null is invalid |
skills, commands, agents |
Path string, array of path strings, null, or omitted |
hooks, mcpServers, lspServers |
Path string or inline JSON value; interpreted by the component loader |
A malformed directory-path list rejects the manifest as a whole; Grok does not load just the string elements from a mixed list. Component advice is skipped when a typed-field error has already prevented the manifest from loading.
Warnings — the plugin registers, but declared components may not load:
- A declared
skills,commands,agents,hooks, ormcpServerspath that resolves outside the plugin package. Contained absolute or parent-normalized spellings remain valid. - A declared path that does not exist on disk.
- A path pointing to the wrong resource type (e.g. specifying a file where a directory is expected, or vice versa).
- Specifying
hooksormcpServersas an array (each should be a file path string or an inline object). - Specifying custom component path overrides that omit existing conventional
directories (e.g. setting
"skills": ["extra-skills"]without also listing"skills").
Info — metadata recommendations for marketplace discovery:
- A
versionthat is not valid semantic versioning. - A missing
description.
What is not reported¶
- Name vs directory: the manifest
nametakes precedence, so differences between manifest name and directory name are supported. - Unknown manifest keys: custom metadata keys are permitted, including
duplicates. Duplicate unknown
authormembers and inline JSON object keys are also accepted; this does not permit duplicate recognized struct fields. - Bare strings for paths: strings and arrays are both supported for
skills,commands, andagents.
Examples¶
Bad — custom skills path omits the existing skills/ directory:
{
"name": "tide-charts",
"version": "1.1.0",
"description": "Shoreline survey windows from NOAA tide predictions.",
"skills": ["./extra-skills"]
}
Good — lists both the extra skills directory and the standard skills/:
{
"name": "tide-charts",
"version": "1.1.0",
"description": "Shoreline survey windows from NOAA tide predictions.",
"skills": ["./extra-skills", "./skills"]
}
How to fix¶
- Choose a valid lowercase kebab-case
name(e.g.tide-charts). - When overriding component locations, include the standard directory alongside any extra paths if you want both loaded.
- Ensure all declared paths exist relative to the plugin root.
- Add a helpful
descriptionand semanticversionfor marketplace listings.
If your project generates component directories during a build step, you can disable path existence checks:
If you intentionally replace conventional directories with custom ones:
Plugin component paths follow canonical containment, independently of the
marketplace source grammar. Contained paths such as nested/../skills remain
valid, and an empty directory-field path names the plugin root. These paths
still participate in override coverage; a path outside the plugin or a target
of the wrong kind remains a warning.
Configuration¶
| Parameter | Description | Default |
|---|---|---|
check-paths-exist |
Warn when a manifest path (skills, commands, agents, hooks, mcpServers) names something the plugin does not contain | true |
check-overrides |
Warn when a declared skills, commands or agents path drops components the conventional directory would have loaded | true |
Run skillsaw explain grok-plugin-json-valid to see this documentation and the rule's effective configuration in your terminal.