Tencent/WeKnora · error

file path outside skill directory: %s

Error message

file path outside skill directory: %s

What it means

Second-layer containment guard in LoadSkillFile: even after Clean passes the first check, the absolutized fullPath does not lie under the absolutized skill BasePath (symlinks or join tricks can escape). Defense-in-depth rejection of any resolved path outside the skill directory.

Source

Thrown at internal/agent/skills/loader.go:228

	// Security: prevent path traversal
	if strings.HasPrefix(cleanPath, "..") || filepath.IsAbs(cleanPath) {
		return nil, fmt.Errorf("invalid file path: %s", relativePath)
	}

	fullPath := filepath.Join(skill.BasePath, cleanPath)

	// Verify the file is within the skill directory
	absSkillPath, err := filepath.Abs(skill.BasePath)
	if err != nil {
		return nil, err
	}
	absFilePath, err := filepath.Abs(fullPath)
	if err != nil {
		return nil, err
	}
	if !strings.HasPrefix(absFilePath, absSkillPath) {
		return nil, fmt.Errorf("file path outside skill directory: %s", relativePath)
	}

	// Read the file
	content, err := os.ReadFile(fullPath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file: %w", err)
	}

	return &SkillFile{
		Name:     relativePath,
		Path:     absFilePath, // Use absolute path for sandbox execution
		Content:  string(content),
		IsScript: IsScript(relativePath),
	}, nil
}

// ListSkillFiles lists all files in a skill directory
func (l *Loader) ListSkillFiles(skillName string) ([]string, error) {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Ensure the requested file physically resides inside the skill's base directory
  2. Remove or replace symlinks in the skill directory that point outside it
  3. Verify BasePath itself resolves to the intended absolute directory
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/agent/skills/loader.go:228 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/8201f1980a5bdf9b. Report an issue: GitHub.