{"record":{"id":"d85c1fb23d65f4ae","repo":"github/spec-kit","slug":"missing-requires-speckit-version-d85c1f","errorCode":null,"errorMessage":"Missing requires.speckit_version","messagePattern":"Missing requires\\.speckit_version","errorType":"validation","errorClass":"PresetValidationError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/presets/__init__.py","lineNumber":363,"sourceCode":"                )\n\n        # Validate pack ID format\n        if not re.match(r'^[a-z0-9-]+$', pack[\"id\"]):\n            raise PresetValidationError(\n                f\"Invalid preset ID '{pack['id']}': \"\n                \"must be lowercase alphanumeric with hyphens only\"\n            )\n\n        # Validate semantic version\n        try:\n            pkg_version.Version(pack[\"version\"])\n        except pkg_version.InvalidVersion:\n            raise PresetValidationError(f\"Invalid version: {pack['version']}\")\n\n        # Validate requires section\n        requires = self.data[\"requires\"]\n        if \"speckit_version\" not in requires:\n            raise PresetValidationError(\"Missing requires.speckit_version\")\n        # Presence alone is not enough: check_compatibility() feeds this value to\n        # ``SpecifierSet(required)``, guarded only by ``except InvalidSpecifier``,\n        # which a non-string escapes two different ways. A float/int/bool/None\n        # raises TypeError from the constructor, while a list or dict is an\n        # *iterable*, so SpecifierSet accepts it and the failure surfaces much\n        # later as ``AttributeError: 'str' object has no attribute 'filter'`` from\n        # inside .contains(). Neither is a PresetCompatibilityError, so both\n        # bypass the CLI's \"Compatibility Error\" handler and exit 1 with a raw\n        # traceback naming no field. An unquoted ``speckit_version: 1.0`` is an\n        # easy YAML slip. Mirrors the sibling IntegrationDescriptor, which already\n        # requires a non-empty string here.\n        if (\n            not isinstance(requires[\"speckit_version\"], str)\n            or not requires[\"speckit_version\"].strip()\n        ):\n            raise PresetValidationError(\n                \"Invalid requires.speckit_version: expected a non-empty string, \"\n                f\"got {type(requires['speckit_version']).__name__}\"","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/presets/__init__.py#L345-L381","documentation":"Error \"Missing requires.speckit_version\" thrown in github/spec-kit.","triggerScenarios":"Thrown at src/specify_cli/presets/__init__.py:363 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Add requires.speckit_version to the preset manifest."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}