{"record":{"id":"85e10c6db0fc4e31","repo":"Tencent/WeKnora","slug":"invalid-skill-file-path-s","errorCode":null,"errorMessage":"invalid skill file path: %s","messagePattern":"invalid skill file path: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/skills/tenant_source.go","lineNumber":272,"sourceCode":"\treturn path.Join(basePath, clean), nil\n}\n\nfunc (s *TenantSkillSource) row(name string) (*types.TenantSkillEntity, error) {\n\tif row, ok := s.byName[name]; ok {\n\t\treturn row, nil\n\t}\n\treturn nil, fmt.Errorf(\"skill not found: %s\", name)\n}\n\n// safeSkillRelPath normalises a caller-supplied relative path and refuses\n// anything that leaves the skill directory.\nfunc safeSkillRelPath(relativePath string) (string, error) {\n\ttrimmed := strings.TrimSpace(relativePath)\n\tif trimmed == \"\" {\n\t\treturn \"\", fmt.Errorf(\"skill file path is required\")\n\t}\n\tif path.IsAbs(trimmed) {\n\t\treturn \"\", fmt.Errorf(\"invalid skill file path: %s\", relativePath)\n\t}\n\tclean := path.Clean(trimmed)\n\tif clean == \".\" || clean == \"..\" || strings.HasPrefix(clean, \"../\") {\n\t\treturn \"\", fmt.Errorf(\"invalid skill file path: %s\", relativePath)\n\t}\n\treturn clean, nil\n}\n\n// bundleArchive returns the compressed zip of one skill, downloading it at\n// most once per cache lifetime.\nfunc (s *TenantSkillSource) bundleArchive(\n\trow *types.TenantSkillEntity,\n) ([]byte, error) {\n\tif s.loadBundle == nil {\n\t\treturn nil, fmt.Errorf(\"skill bundles are not available in this deployment\")\n\t}\n\n\tkey := strings.TrimSpace(row.BundleSHA256)","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/skills/tenant_source.go#L254-L290","documentation":"Path-safety guard in safeSkillRelPath: the trimmed relative path is absolute (or otherwise rejected by the normalization rules, e.g. escaping the skill directory). The check refuses anything that could resolve outside the skill directory; the offending caller-supplied path is interpolated into the message.","triggerScenarios":"Thrown at internal/agent/skills/tenant_source.go:272 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass a relative path that stays inside the skill directory (no leading \"/\", no \"..\")","Strip absolute prefixes client-side before requesting the file","Log the rejected path as a potential traversal attempt"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}