{"record":{"id":"ffa1c0b235115b7c","repo":"Tencent/WeKnora","slug":"file-path-belongs-to-skill-q-call-read-skill-ski","errorCode":null,"errorMessage":"file_path belongs to skill %q; call read_skill(skill_name=%q, file_path=...)","messagePattern":"file_path belongs to skill %q; call read_skill\\(skill_name=%q, file_path=\\.\\.\\.\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/skill_read.go","lineNumber":261,"sourceCode":"// works. Workspace paths are rejected here; they belong to other tools.\nfunc skillRelativeFilePath(skillName, filePath string) (string, error) {\n\ttrimmed := strings.TrimSpace(filePath)\n\tif trimmed == \"\" {\n\t\treturn \"\", nil\n\t}\n\tclean := path.Clean(trimmed)\n\tif path.IsAbs(trimmed) {\n\t\tdir, err := sandbox.SkillDirFor(skillName)\n\t\tif err == nil {\n\t\t\tif clean == dir {\n\t\t\t\treturn \"\", nil\n\t\t\t}\n\t\t\tif strings.HasPrefix(clean, dir+\"/\") {\n\t\t\t\treturn strings.TrimPrefix(clean, dir+\"/\"), nil\n\t\t\t}\n\t\t}\n\t\tif other, inImage := sandbox.SkillNameFromImagePath(clean); inImage && other != \"\" && other != skillName {\n\t\t\treturn \"\", fmt.Errorf(\n\t\t\t\t\"file_path belongs to skill %q; call read_skill(skill_name=%q, file_path=...)\",\n\t\t\t\tother, other,\n\t\t\t)\n\t\t}\n\t\treturn \"\", fmt.Errorf(\n\t\t\t\"file_path must be relative inside the skill (e.g. scripts/generate_ppt.py), not %s\",\n\t\t\tfilePath,\n\t\t)\n\t}\n\tprefix := skillName + \"/\"\n\tif strings.HasPrefix(clean, prefix) {\n\t\treturn strings.TrimPrefix(clean, prefix), nil\n\t}\n\treturn clean, nil\n}\n\n// Cleanup releases any resources (implements Tool interface if needed)\nfunc (t *ReadSkillTool) Cleanup(ctx context.Context) error {","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/agent/tools/skill_read.go#L243-L279","documentation":"Skill-file path routing guard: the absolute file_path resolves inside a different skill's image directory (derived via SkillNameFromImagePath) than the skill being read, so the helper rejects it and redirects the caller to read_skill with the owning skill's name to prevent cross-skill file access.","triggerScenarios":"Thrown at internal/agent/tools/skill_read.go:261 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Call read_skill with skill_name set to the skill that owns the file","Keep file_path relative to the current skill","Do not reference another skill's image paths directly"],"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"}