{"record":{"id":"5dceaf4cb0061790","repo":"Tencent/WeKnora","slug":"failed-to-write-file-w","errorCode":null,"errorMessage":"failed to write file: %w","messagePattern":"failed to write file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/file/local.go","lineNumber":243,"sourceCode":"\t}\n\n\t// Create storage directory with tenant ID\n\tdir := filepath.Join(s.baseDir, fmt.Sprintf(\"%d\", tenantID), \"exports\")\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\tlogger.Errorf(ctx, \"Failed to create directory: %v\", err)\n\t\treturn \"\", fmt.Errorf(\"failed to create directory: %w\", err)\n\t}\n\n\t// Generate unique filename using timestamp\n\text := filepath.Ext(safeName)\n\tbaseName := safeName[:len(safeName)-len(ext)]\n\tuniqueFileName := fmt.Sprintf(\"%s_%d%s\", baseName, time.Now().UnixNano(), ext)\n\tfilePath := filepath.Join(dir, uniqueFileName)\n\n\t// Write data to file\n\tif err := os.WriteFile(filePath, data, 0o644); err != nil {\n\t\tlogger.Errorf(ctx, \"Failed to write file: %v\", err)\n\t\treturn \"\", fmt.Errorf(\"failed to write file: %w\", err)\n\t}\n\n\tlogger.Infof(ctx, \"Bytes data saved successfully: %s\", filePath)\n\trelPath, _ := filepath.Rel(s.baseDir, filePath)\n\treturn localScheme + filepath.ToSlash(relPath), nil\n}\n\n// GetFileURL returns a download URL for the file.\n// When externalURL is configured, returns a presigned HTTP URL suitable for external access.\n// Otherwise returns the local://... path for backward compatibility.\nfunc (s *localFileService) GetFileURL(ctx context.Context, filePath string) (string, error) {\n\t// Normalize to provider:// format.\n\tnormalized := filePath\n\tif !strings.HasPrefix(filePath, localScheme) {\n\t\trelPath, err := filepath.Rel(s.baseDir, filePath)\n\t\tif err != nil {\n\t\t\tnormalized = filePath\n\t\t} else {","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/file/local.go#L225-L261","documentation":"SaveBytes wraps any error from os.WriteFile when writing the byte payload to the uniquely named file under baseDir/<tenantID>/exports as \"failed to write file: %w\". The directory was already created successfully, so this error is specifically about creating/writing the final file, with the original OS error preserved for unwrapping.","triggerScenarios":"os.WriteFile(filePath, data, 0o644) fails: path component vanished between MkdirAll and WriteFile, permission denied on the directory, disk full so the write is short, file name too long after the timestamp suffix, or a symlink/race replaces the target path.","commonSituations":"Disk quota exceeded for the tenant volume; read-only mount discovered only at write time; baseDir on tmpfs that ran out of space for large uploads; concurrent cleanup job deleting the exports dir mid-write; SELinux/AppArmor denying write to the path.","solutions":["Unwrap with errors.Is(err, fs.ErrPermission) / syscall.ENOSPC and address accordingly: fix directory permissions or free disk/quota space","Confirm the volume backing baseDir is mounted read-write and has enough free space for the payload size (df -h)","Check for background cleanup/rsync jobs racing on the exports directory and exclude in-flight writes","If SELinux denies writes, relabel the directory (restorecon) or adjust the container security policy","Retry SaveBytes with backoff for transient ENOSPC/EIO conditions"],"exampleFix":"// before\npath, err := svc.SaveBytes(ctx, data, tenantID, \"report.csv\", false)\nif err != nil {\n    log.Fatal(err) // opaque\n}\n// after\npath, err := svc.SaveBytes(ctx, data, tenantID, \"report.csv\", false)\nif err != nil {\n    if errors.Is(err, syscall.ENOSPC) {\n        // free space / alert ops, then retry\n    } else if errors.Is(err, fs.ErrPermission) {\n        // fix permissions on baseDir\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"func ensureFreeSpace(dir string, need uint64) error {\n    var st syscall.Statfs_t\n    if err := syscall.Statfs(dir, &st); err != nil {\n        return err\n    }\n    avail := st.Bavail * uint64(st.Bsize)\n    if avail < need*2 { // headroom for the payload\n        return fmt.Errorf(\"insufficient space in %s: %d < %d\", dir, avail, need*2)\n    }\n    return nil\n}\n// call before SaveBytes: ensureFreeSpace(exportsDir, uint64(len(data)))","typeGuard":null,"tryCatchPattern":"path, err := svc.SaveBytes(ctx, data, tenantID, name, false)\nif err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && errors.Is(perr.Err, syscall.ENOSPC) {\n        // alert / free space, then retry with backoff\n    }\n    return fmt.Errorf(\"save failed: %w\", err)\n}","preventionTips":["Check available disk space (or quota) before writing large payloads","Keep baseDir on a volume with monitoring and low-disk alerts","Avoid aggressive cleanup jobs that could remove the exports dir between MkdirAll and WriteFile","Set sensible retention policies so the export volume does not fill up"],"tags":["filesystem","io","storage","disk-full"],"backgroundTag":"file-write-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}