Tencent/WeKnora · error
invalid file path: %w
Error message
invalid file path: %w
What it means
ks3FileService.GetFile wraps SafeObjectKey failures with "invalid file path: %w" before fetching the object. SafeObjectKey rejects object keys that are empty or contain ".." (path traversal). The ks3:// path must already have parsed successfully, so this error means the key inside a well-formed ks3://bucket/key path failed the security sanitization check.
Source
Thrown at internal/application/service/file/ks3.go:223
SourceBucket: ks3aws.String(srcBucket),
SourceKey: ks3aws.String(srcKey),
})
if err != nil {
return "", fmt.Errorf("failed to copy file in KS3: %w", err)
}
newPath := fmt.Sprintf("%s%s/%s", ks3Scheme, s.bucketName, destKey)
logger.Infof(ctx, "Copied KS3 object %s to %s", srcPath, newPath)
return newPath, nil
}
func (s *ks3FileService) GetFile(ctx context.Context, filePath string) (io.ReadCloser, error) {
_, objectKey, err := parseKS3FilePath(filePath)
if err != nil {
return nil, err
}
if err := utils.SafeObjectKey(objectKey); err != nil {
return nil, fmt.Errorf("invalid file path: %w", err)
}
resp, err := s.client.GetObject(&ks3s3.GetObjectInput{
Bucket: ks3aws.String(s.bucketName),
Key: ks3aws.String(objectKey),
})
if err != nil {
return nil, fmt.Errorf("failed to get file from KS3: %w", err)
}
return resp.Body, nil
}
func (s *ks3FileService) DeleteFile(ctx context.Context, filePath string) error {
_, objectKey, err := parseKS3FilePath(filePath)
if err != nil {
return err
}View on GitHub (pinned to 988cbb0330)
Solutions
- Remove any ".." segments from the object key; keys are joined by joinKS3Key from pathPrefix/tenantID/knowledgeID/uuid, so store and pass only the path returned by SaveFile/SaveBytes.
- Verify the stored file path starts with "ks3://" and has both bucket and non-empty key components (parseKS3FilePath already passed, so check the key only).
- If paths came from an old schema, run a data cleanup that strips or rejects keys containing ".." before calling GetFile.
- Log the offending filePath and re-upload the file with SaveFile to get a canonical safe key.
Example fix
// before rc, err := svc.GetFile(ctx, "ks3://bucket/tenant/1/../1/doc.pdf") // after rc, err := svc.GetFile(ctx, "ks3://bucket/prefix/1/knowledge-id/550e8400-e29b-41d4.pdf")
Defensive patterns
Strategy: validation
Validate before calling
func validKS3Path(p string) bool {
if !strings.HasPrefix(p, "ks3://") { return false }
rest := strings.TrimPrefix(p, "ks3://")
parts := strings.SplitN(rest, "/", 2)
return len(parts) == 2 && parts[0] != "" && parts[1] != "" && !strings.Contains(parts[1], "..")
} Prevention
- Only pass paths previously returned by SaveFile/SaveBytes/CopyFile
- Reject client-supplied file paths containing ".." at the API boundary
- Never build ks3:// strings by concatenating user input
When it happens
Trigger: Calling GetFile with a ks3:// path whose object key is empty or contains "..", e.g. "ks3://mybucket/a/../secret" or "ks3://mybucket/". Typically comes from tampered or hand-constructed path strings persisted in the DB.
Common situations: Imported knowledge-base records with attacker-influenced file paths; tests injecting traversal keys; migrating records from another backend where keys contained dot-dot segments; string concatenation bugs producing keys like "tenant/1/../2/file".
Related errors
- failed to get file from KS3: %w
- failed to delete file from KS3: %w
- invalid path: %w
- member_limit must be >= 0
- missing query parameter
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/e692b6d54870f3e3.
Report an issue: GitHub.