{"record":{"id":"bee125325c8c236e","repo":"Tencent/WeKnora","slug":"failed-to-get-file-from-s3-w","errorCode":null,"errorMessage":"failed to get file from S3: %w","messagePattern":"failed to get file from S3: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/file/s3.go","lineNumber":268,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"failed to upload file to S3: %w\", err)\n\t}\n\n\treturn fmt.Sprintf(\"s3://%s/%s\", s.bucketName, objectName), nil\n}\n\n// GetFile gets a file from S3\nfunc (s *s3FileService) GetFile(ctx context.Context, filePath string) (io.ReadCloser, error) {\n\tobjectName, err := s.parseS3FilePath(filePath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := s.client.GetObject(ctx, &s3.GetObjectInput{\n\t\tBucket: aws.String(s.bucketName),\n\t\tKey:    aws.String(objectName),\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get file from S3: %w\", err)\n\t}\n\n\treturn resp.Body, nil\n}\n\n// DeleteFile deletes a file\nfunc (s *s3FileService) DeleteFile(ctx context.Context, filePath string) error {\n\tobjectName, err := s.parseS3FilePath(filePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = s.client.DeleteObject(ctx, &s3.DeleteObjectInput{\n\t\tBucket: aws.String(s.bucketName),\n\t\tKey:    aws.String(objectName),\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete file: %w\", err)","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/file/s3.go#L250-L286","documentation":"GetFile wraps any error returned by the AWS S3 GetObject call with 'failed to get file from S3'. It means the object could not be read from the bucket — either the key does not exist, credentials/permissions are insufficient, or the S3 call failed at the network level. The underlying S3 error is preserved via %w for errors.Is/As inspection.","triggerScenarios":"Calling GetFile with an objectName/key that does not exist in the bucket (NoSuchKey), expired or misconfigured credentials, missing s3:GetObject permission on the bucket/key, or network/DNS failures reaching the S3 endpoint.","commonSituations":"File was deleted or never uploaded under the constructed path (pathPrefix/tenantID/... changed between versions); wrong bucketName in config; IAM policy lacks GetObject; SDK v2 endpoint misconfiguration; VPC without outbound access to S3.","solutions":["Verify the object exists (aws s3 ls s3://bucket/objectName) and that the objectName passed to GetFile matches the path returned by SaveFile/SaveBytes","Check AWS credentials and IAM policy grant s3:GetObject on bucket/objectName","Unwrap the error with errors.As on smithy APIError to distinguish NoSuchKey vs AccessDenied vs network errors","Confirm bucketName and region/endpoint configuration are correct for the environment"],"exampleFix":"// before\nbody, err := fileSvc.GetFile(ctx, path)\n// after\nbody, err := fileSvc.GetFile(ctx, path)\nif err != nil {\n    var apiErr smithy.APIError\n    if errors.As(err, &apiErr) && apiErr.ErrorCode() == \"NotFound\" {\n        return fmt.Errorf(\"file %s not found: %w\", path, err)\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// Go: check path format before calling\nif !strings.HasPrefix(path, \"s3://\") { return errors.New(\"not an s3 path\") }","typeGuard":"func isS3Path(p string) bool { return strings.HasPrefix(p, \"s3://\") }","tryCatchPattern":"body, err := svc.GetFile(ctx, path)\nif err != nil {\n    var apiErr smithy.APIError\n    if errors.As(err, &apiErr) && apiErr.ErrorCode() == \"NotFound\" {\n        return ErrFileNotFound\n    }\n    return err\n}","preventionTips":["Always use paths returned by SaveFile/SaveBytes as input to GetFile","Map S3 error codes (NotFound, AccessDenied) to domain errors via errors.As","Log bucket/key on failure to speed up debugging","Keep bucket policy and IAM in sync with the pathPrefix scheme"],"tags":["aws","s3","network","storage"],"backgroundTag":"s3-getobject-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}