Billionmail/BillionMail · error
error saving site map file: %v
Error message
error saving site map file: %v
What it means
SaveSiteMap writes the marshalled sitemap to PRODUCT_CONFIG_PATH/<domain>/sitemap.json via os.WriteFile with 0644. This error wraps any write failure: the domain config directory missing (SaveSiteMap never creates it), permission denial, read-only filesystem, or disk-full.
Source
Thrown at core/internal/service/askai/project.go:639
}
var siteMap []SiteMap
err = json.Unmarshal(data, &siteMap)
if err != nil {
return nil, fmt.Errorf("error unmarshalling site map: %v", err)
}
return siteMap, nil
}
func SaveSiteMap(Domain string, siteMap []SiteMap) error {
filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/sitemap.json", Domain)
data, err := json.MarshalIndent(siteMap, "", " ")
if err != nil {
return fmt.Errorf("error marshalling site map: %v", err)
}
err = os.WriteFile(filename, data, 0644)
if err != nil {
return fmt.Errorf("error saving site map file: %v", err)
}
return nil
}
// AddSiteMapNode adds a new site map node with the provided title and URI path to the site map of the specified domain.
// It reads the existing site map, appends the new node, and saves the updated site map back to the file.
// If the site map file does not exist or cannot be read, it returns an error.
func AddSiteMapNode(Domain string, Title string, UriPath string) error {
siteMap, err := GetSiteMap(Domain)
if err != nil {
return fmt.Errorf("error getting site map: %v", err)
}
newNode := SiteMap{
Title: Title,
UriPath: UriPath,
UpdateTime: public.GetNowTime(),
}View on GitHub (pinned to fc36c76c05)
Solutions
- Create the directory before writing: os.MkdirAll(filepath.Dir(filename), 0755) in SaveSiteMap or at domain provisioning.
- Check ownership/permissions of PRODUCT_CONFIG_PATH/<domain>/ (chown/chmod for the service user).
- Confirm the nested os error text to distinguish 'no such file or directory' from 'permission denied' or 'no space left on device'.
- Free disk space or remount the volume read-write if the cause is disk/quota related.
Example fix
// before
filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/sitemap.json", Domain)
data, _ := json.MarshalIndent(siteMap, "", " ")
err := os.WriteFile(filename, data, 0644)
// after
filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/sitemap.json", Domain)
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
return fmt.Errorf("error creating sitemap dir: %v", err)
}
data, _ := json.MarshalIndent(siteMap, "", " ")
err := os.WriteFile(filename, data, 0644) Defensive patterns
Strategy: try-catch
Validate before calling
func ensureSitemapDir(domain string) error {
dir := filepath.Join(PRODUCT_CONFIG_PATH, domain)
if err := os.MkdirAll(dir, 0755); err != nil { return err }
if info, err := os.Stat(dir); err != nil || !info.IsDir() {
return fmt.Errorf("%s not writable dir", dir)
}
return nil
} Try / catch
if err := SaveSiteMap(domain, siteMap); err != nil {
switch {
case errors.Is(err, os.ErrNotExist):
os.MkdirAll(filepath.Join(PRODUCT_CONFIG_PATH, domain), 0755)
err = SaveSiteMap(domain, siteMap) // retry once after mkdir
case errors.Is(err, os.ErrPermission):
log.Printf("permission denied writing sitemap for %s", domain)
}
return err
} Prevention
- Have SaveSiteMap MkdirAll its target directory before writing.
- Keep config volumes read-write and monitor disk usage/quota.
- Chown PRODUCT_CONFIG_PATH to the service user in deployment scripts.
When it happens
Trigger: Calling SaveSiteMap (or AppendSitemap) when PRODUCT_CONFIG_PATH/<domain>/ does not exist (ENOENT), when the process cannot write there (EACCES/EPERM), or on a full/read-only filesystem.
Common situations: Adding a sitemap node for a domain whose config directory was never provisioned; running under a different user after a migration; Docker volume mounted read-only; disk quota exceeded.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- error saving empty site map file: %v
- error reading footer config file: %v
- error reading project configuration file: %v
- error writing project configuration file: %v
- error writing knowledge base file: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/9160b857d254fd1f.
Report an issue: GitHub.