Skip to content

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 name that 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, or mcpServers path 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 hooks or mcpServers as 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 version that is not valid semantic versioning.
  • A missing description.

What is not reported

  • Name vs directory: the manifest name takes precedence, so differences between manifest name and directory name are supported.
  • Unknown manifest keys: custom metadata keys are permitted, including duplicates. Duplicate unknown author members 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, and agents.

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 description and semantic version for marketplace listings.

If your project generates component directories during a build step, you can disable path existence checks:

rules:
  grok-plugin-json-valid:
    check-paths-exist: false

If you intentionally replace conventional directories with custom ones:

rules:
  grok-plugin-json-valid:
    check-overrides: false

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

rules:
  grok-plugin-json-valid:
    enabled: auto  # true | false | auto
    severity: error
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.