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

  1. 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.
  2. 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).
  3. If paths came from an old schema, run a data cleanup that strips or rejects keys containing ".." before calling GetFile.
  4. 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

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


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