{"record":{"id":"5e4c51e64f64c9a2","repo":"langchain-ai/deepagents","slug":"error-path-error","errorCode":null,"errorMessage":"Error: {path_error}","messagePattern":"Error: (.+?)","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/skills/commands.py","lineNumber":464,"sourceCode":"                style=theme.MUTED,\n            )\n            raise SystemExit(1)\n        skills_dir = ensure_project_skills_dir(credentials.project_root)\n        if skills_dir is None:\n            console.print(\n                \"[bold red]Error:[/bold red] Could not create project skills directory.\"\n            )\n            raise SystemExit(1)\n    else:\n        skills_dir = ensure_user_skills_dir(agent)\n\n    skill_dir = skills_dir / skill_name\n\n    # Validate the resolved path is within skills_dir\n    is_valid_path, path_error = _validate_skill_path(skill_dir, skills_dir)\n    if not is_valid_path:\n        console.print(f\"[bold red]Error:[/bold red] {path_error}\")\n        raise SystemExit(1)\n\n    if skill_dir.exists():\n        if output_format == \"json\":\n            from deepagents_code.output import write_json\n\n            write_json(\n                \"skills create\",\n                {\n                    \"name\": skill_name,\n                    \"path\": str(skill_dir),\n                    \"project\": project,\n                    \"already_existed\": True,\n                },\n            )\n            return\n        console.print(\n            f\"Skill '{skill_name}' already exists at {skill_dir}\",\n            style=theme.MUTED,","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/skills/commands.py#L446-L482","documentation":"The resolved skill directory path failed `_validate_skill_path`, meaning the skill name resolves outside the intended skills directory — typically a path-traversal attempt (e.g. a skill name containing `/`, `..`, or absolute-path components). This guard prevents creating skills in arbitrary filesystem locations.","triggerScenarios":"`dcode skills create` with a `skill_name` such as `../escape`, `a/b`, or `/etc/foo`, causing `skills_dir / skill_name` to resolve outside `skills_dir` per the containment check.","commonSituations":"Typing a slash-separated name instead of using nested directories as intended, scripting the command with unvalidated user input, or copy-pasting a path as the skill name.","solutions":["Use a name matching the Agent Skills spec: lowercase letters, digits, and hyphens only (e.g. `my-skill`), no slashes or `..`","Sanitize/validate any programmatically supplied skill name before invoking the command","If you need a nested skill path, create it through the intended skill structure rather than encoding directories in the name"],"exampleFix":"// before\ndcode skills create \"../shared/skill\"\n// after\ndcode skills create \"shared-skill\"","handlingStrategy":"validation","validationCode":"import re\n\ndef is_valid_skill_name(name: str) -> bool:\n    return bool(re.fullmatch(r\"[a-z0-9]+(-[a-z0-9]+)*\", name)) and \"..\" not in name\n\nassert is_valid_skill_name(\"my-skill\")","typeGuard":"def safe_skill_name(name: object) -> str | None:\n    if isinstance(name, str) and re.fullmatch(r\"[a-z0-9][a-z0-9-]*\", name) and \"/\" not in name:\n        return name\n    return None","tryCatchPattern":null,"preventionTips":["Restrict skill names to lowercase alphanumerics and hyphens","Never pass paths or user-supplied raw strings as skill names","Sanitize names in scripts before invoking the CLI"],"tags":["cli","path-traversal","validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}