Tencent/WeKnora · error
save: %w
Error message
save: %w
What it means
This error wraps a failure from fileSvc.SaveBytes when persisting a downloaded remote image to storage. The image bytes were fetched successfully but could not be saved under a generated UUID filename for the tenant.
Source
Thrown at internal/infrastructure/docparser/image_resolver.go:812
if isIconImage(data) {
return nil, errRemoteImageIsIcon
}
if whitelisted {
return &remoteImageResult{MimeType: mimeType, KeepOriginalURL: true}, nil
}
ext := extFromMime(mimeType)
if ext == "" {
ext = extFromURLPath(imgURL)
}
if ext == "" {
ext = ".png" // safe default
}
servingURL, err := fileSvc.SaveBytes(ctx, data, tenantID, uuid.New().String()+ext, false)
if err != nil {
return nil, fmt.Errorf("save: %w", err)
}
return &remoteImageResult{ServingURL: servingURL, MimeType: mimeType}, nil
}
// isRemoteHTTPURL reports whether raw is an absolute http(s) URL.
//
// The comparison is deliberately byte-exact. Downstream fetchers compare the
// scheme the same way, so anything accepted here has to be spelled the way they
// expect; per-syntax normalization belongs in the SrcOf of the scan that needs
// it, not in this predicate.
func isRemoteHTTPURL(raw string) bool {
return strings.HasPrefix(raw, "http://") || strings.HasPrefix(raw, "https://")
}
// remotePassSpec describes one scan of a document: which references it matches,
// where the URL sits inside a match, and how to turn the raw document bytes into
// the URL to request.
type remotePassSpec struct {View on GitHub (pinned to 988cbb0330)
Solutions
- Unwrap the error and check the storage backend's specific failure
- Verify storage service credentials, endpoint, and bucket configuration
- Check tenant storage quota and available disk space
- Confirm tenantID is valid and the tenant's storage location is provisioned
Example fix
// before
servingURL, err := fileSvc.SaveBytes(ctx, data, tenantID, uuid.New().String()+ext, false)
if err != nil { return nil, fmt.Errorf("save: %w", err) }
// after
servingURL, err := fileSvc.SaveBytes(ctx, data, tenantID, uuid.New().String()+ext, false)
if err != nil {
return nil, fmt.Errorf("save image for tenant %s: %w", tenantID, err) // add tenant context
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify storage backend is writable before processing
if err := fileSvc.Ping(ctx); err != nil {
return fmt.Errorf("storage backend unavailable: %w", err)
} Try / catch
res, err := resolver.fetchAndStoreRemoteImage(ctx, imgURL, tenantID)
if err != nil {
if strings.HasPrefix(err.Error(), "save:") {
// storage-side failure: check backend health/quota, queue for retry
return fmt.Errorf("persist image failed (check storage config/quota): %w", err)
}
return err
} Prevention
- Monitor storage backend health and quotas per tenant
- Validate storage credentials and bucket provisioning at startup
- Set up alerting for storage save failures
- Confirm tenantID validity before processing
When it happens
Trigger: fetchAndStoreRemoteImage calls fileSvc.SaveBytes and it errors: storage backend unavailable, tenant bucket missing, permission denied, quota exceeded, or disk full.
Common situations: S3/OSS/minio credentials misconfigured or expired, storage quota exhausted for the tenant, object storage outage, network partition to storage backend, invalid tenantID.
Related errors
- failed to write file: %w
- read body: %w
- bind owned remote sandbox: %w
- create sandbox binding: %w
- script_path %q is a session workspace file; this skill is no
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/298a2f559dd0b092.
Report an issue: GitHub.