{"record":{"id":"404ea10104ec13af","repo":"iOfficeAI/OfficeCLI","slug":"unsupported-plugin-kind","errorCode":"unsupported_plugin_kind","errorMessage":"Plugin '{resolved.Manifest.Name}' is not a dump-reader; lint only applies to dump-reader plugins.","messagePattern":"Plugin '(.+?)' is not a dump-reader; lint only applies to dump-reader plugins\\.","errorType":"exception","errorClass":"CliException","httpStatus":null,"severity":"error","filePath":"src/officecli/CommandBuilder.Plugins.cs","lineNumber":246,"sourceCode":"\n        cmd.SetAction(result => { var json = result.GetValue(jsonOption); return SafeRun(() =>\n        {\n            var target = result.GetValue(nameArg) ?? \"\";\n            var fixturePath = result.GetValue(fixtureOption);\n            var resolved = ResolveByNameOrPath(target)\n                ?? throw new CliException($\"Plugin not found: '{target}'\")\n                {\n                    Code = \"plugin_not_found\",\n                    Suggestion = \"Run `officecli plugins list` to see installed plugins, or provide the absolute path to the plugin executable.\",\n                };\n\n            // Only dump-readers are lintable today — the lint contract is\n            // \"the plugin's emitted batch must use prop keys the schema\n            // recognises\". Exporters and format-handlers have their own\n            // contracts (binary output, vocabulary block) that don't go\n            // through the schema validator.\n            if (!resolved.Manifest.Kinds.Contains(\"dump-reader\"))\n                throw new CliException(\n                    $\"Plugin '{resolved.Manifest.Name}' is not a dump-reader; lint only applies to dump-reader plugins.\")\n                {\n                    Code = \"unsupported_plugin_kind\",\n                    Suggestion = \"Run `officecli plugins info <name>` to see what kinds the plugin advertises.\",\n                };\n\n            // Resolve a fixture: explicit arg → env var. No bundled fallback —\n            // a fixture is a per-plugin concern; the plugin author (or CI)\n            // pins it via --fixture or $OFFICECLI_LINT_FIXTURE.\n            var srcExt = resolved.Manifest.Extensions.FirstOrDefault() ?? \"\";\n            fixturePath ??= Environment.GetEnvironmentVariable(\"OFFICECLI_LINT_FIXTURE\");\n            if (string.IsNullOrEmpty(fixturePath) || !File.Exists(fixturePath))\n                throw new CliException(\n                    $\"No lint fixture available for plugin '{resolved.Manifest.Name}'\" +\n                    (string.IsNullOrEmpty(srcExt) ? \"\" : $\" ({srcExt})\") + \". \" +\n                    \"Pass --fixture <path>, or set OFFICECLI_LINT_FIXTURE.\")\n                {\n                    Code = \"lint_fixture_missing\",","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/src/officecli/CommandBuilder.Plugins.cs#L228-L264","documentation":"The lint command only applies to plugins whose manifest advertises the 'dump-reader' kind, because lint's contract is 'the plugin's emitted batch uses prop keys the target schema recognises'. Exporters and format-handlers have different contracts (binary output, vocabulary block) and are not schema-validatable this way.","triggerScenarios":"'officecli plugins lint <plugin>' where the plugin's manifest Kinds does not contain 'dump-reader' (e.g. an exporter-only or format-handler plugin).","commonSituations":"Trying to lint a plugin that only exports or handles formats; a plugin whose manifest is missing the 'dump-reader' kind declaration.","solutions":["Check the plugin's kinds: 'officecli plugins info <name>'.","Only run lint on dump-reader plugins.","If the plugin should be a dump-reader, add 'dump-reader' to its manifest Kinds."],"exampleFix":"// before\nofficecli plugins lint my-exporter\n// after\nofficecli plugins info my-exporter   # confirm kinds\n# lint only dump-readers\nofficecli plugins lint my-dump-reader","handlingStrategy":"validation","validationCode":"var resolved = ResolveByNameOrPath(name)\n    ?? throw new ArgumentException(\"plugin not found\");\nif (!resolved.Manifest.Kinds.Contains(\"dump-reader\"))\n    throw new ArgumentException(\n        $\"Lint is dump-reader only; '{resolved.Manifest.Name}' advertises: {string.Join(\",\", resolved.Manifest.Kinds)}.\");","typeGuard":"static bool IsLintable(PluginManifest m) => m.Kinds.Contains(\"dump-reader\");","tryCatchPattern":null,"preventionTips":["Lint is dump-reader-scoped; check Kinds before linting.","Declare 'dump-reader' in the manifest if the plugin reads foreign formats.","Exporters/format-handlers have their own validation paths."],"tags":["plugins","lint","plugin-kind","dump-reader"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}