{"record":{"id":"3e1365cc473a5562","repo":"github/spec-kit","slug":"type-self-name-config-is-missing-required","errorCode":null,"errorMessage":"{type(self).__name__}.config is missing required 'folder' entry.","messagePattern":"(.+?)\\.config is missing required 'folder' entry\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/integrations/base.py","lineNumber":1601,"sourceCode":"        if model:\n            args.extend([\"--model\", model])\n        if output_json:\n            args.extend([\"--output-format\", \"json\"])\n        return args\n\n    def skills_dest(self, project_root: Path) -> Path:\n        \"\"\"Return the absolute path to the skills output directory.\n\n        Derived from ``config[\"folder\"]`` and the configured\n        ``commands_subdir`` (defaults to ``\"skills\"``).\n\n        Raises ``ValueError`` when ``config`` or ``folder`` is missing.\n        \"\"\"\n        if not self.config:\n            raise ValueError(f\"{type(self).__name__}.config is not set.\")\n        folder = self.config.get(\"folder\")\n        if not folder:\n            raise ValueError(\n                f\"{type(self).__name__}.config is missing required 'folder' entry.\"\n            )\n        subdir = self.config.get(\"commands_subdir\", \"skills\")\n        return project_root / folder / subdir\n\n    def build_command_invocation(self, command_name: str, args: str = \"\") -> str:\n        \"\"\"Build the agent's native invocation for a hyphenated skill name.\"\"\"\n        stem = command_name\n        if stem.startswith(\"speckit.\"):\n            stem = stem[len(\"speckit.\"):]\n\n        prefix = \"$\" if is_dollar_skills_agent(self.key, True) else \"/\"\n        invocation = prefix + \"speckit-\" + stem.replace(\".\", \"-\")\n        if args:\n            invocation = f\"{invocation} {args}\"\n        return invocation\n\n    @staticmethod","sourceCodeStart":1583,"sourceCodeEnd":1619,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/integrations/base.py#L1583-L1619","documentation":"Companion check in SkillsIntegration.skills_dest(): config exists but has no 'folder' key (or it is empty/None). The folder value determines where speckit-<name>/SKILL.md files are installed, so a missing one cannot be defaulted safely. Like its sibling, this is a subclass-authoring error surfaced at install time.","triggerScenarios":"A SkillsIntegration subclass whose config dict omits 'folder' or sets it to \"\" / None; a typo like \"folders\" or \"dir\" instead of \"folder\".","commonSituations":"Hand-writing a new skills integration from memory and misspelling the key; copying a Markdown integration's config and dropping the folder line during trimming.","solutions":["Add a non-empty project-relative folder entry, e.g. \"folder\": \".my-agent/\".","Compare against a known-good skills integration (e.g. claude or codex in this repo) for the exact required keys.","Validate config keys in the integration's test file so the error surfaces in CI, not at install."],"exampleFix":"# before\nconfig = {\"name\": \"My Agent\", \"commands_subdir\": \"skills\"}\n# after\nconfig = {\"name\": \"My Agent\", \"folder\": \".my-agent/\", \"commands_subdir\": \"skills\"}","handlingStrategy":"type-guard","validationCode":"def has_folder_key(integration) -> bool:\n    return bool((getattr(integration, \"config\", None) or {}).get(\"folder\"))","typeGuard":"def skills_config_valid(integration) -> bool:\n    cfg = getattr(integration, \"config\", None) or {}\n    return isinstance(cfg, dict) and bool(cfg.get(\"folder\"))","tryCatchPattern":"try:\n    integration.skills_dest(project_root)\nexcept ValueError as exc:\n    if \"missing required 'folder'\" in str(exc):\n        raise SystemExit(\"add a non-empty project-relative 'folder' to config\") from None\n    raise","preventionTips":["Spell the key exactly 'folder' and give it a non-empty relative path like '.my-agent/'.","Copy the full config dict shape from an existing skills integration (claude, codex).","Cover config completeness in the integration's dedicated test file."],"tags":["integrations","configuration","developer-error","skills"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}