Billionmail/BillionMail · error
error saving empty site map file: %v
Error message
error saving empty site map file: %v
What it means
In the same self-healing branch of GetSiteMap, after marshalling an empty []SiteMap the function attempts os.WriteFile(filename, ..., 0644) to bootstrap sitemap.json. This error wraps the write failure — most commonly because the directory PRODUCT_CONFIG_PATH/<domain>/ does not exist, since GetSiteMap (like SaveStyleConfig) never creates it.
Source
Thrown at core/internal/service/askai/project.go:614
// GetSiteMap retrieves the site map for a given domain from a JSON file.
// It reads the site map file and returns a slice of SiteMap structs.
// If the file does not exist or cannot be read, it returns an error.
func GetSiteMap(Domain string) ([]SiteMap, error) {
filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/sitemap.json", Domain)
if !public.FileExists(filename) {
// If the site map file does not exist, return an empty slice
// This allows the system to handle cases where the site map has not been set up
// and avoids errors when trying to read a non-existent file.
// It also allows the user to create a new site map without needing to handle file not found errors.
emptySiteMap := []SiteMap{}
emptySiteMapJson, err := json.MarshalIndent(emptySiteMap, "", " ")
if err != nil {
return nil, fmt.Errorf("error marshalling empty site map: %v", err)
}
err = os.WriteFile(filename, emptySiteMapJson, 0644)
if err != nil {
return nil, fmt.Errorf("error saving empty site map file: %v", err)
}
return emptySiteMap, nil
}
data, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("error reading site map file: %v", err)
}
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)View on GitHub (pinned to fc36c76c05)
Solutions
- Create the domain config directory before writing: os.MkdirAll(filepath.Dir(filename), 0755) in GetSiteMap's bootstrap branch.
- Check permissions/ownership of PRODUCT_CONFIG_PATH/<domain>/ for the service user (chown/chmod).
- Confirm PRODUCT_CONFIG_PATH points to an existing, writable base directory.
- Read the nested os error to confirm the cause (e.g. 'no such file or directory' vs 'permission denied').
Example fix
// before
err = os.WriteFile(filename, emptySiteMapJson, 0644)
if err != nil { return nil, fmt.Errorf("error saving empty site map file: %v", err) }
// after
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
return nil, fmt.Errorf("error creating sitemap dir: %v", err)
}
err = os.WriteFile(filename, emptySiteMapJson, 0644)
if err != nil { return nil, fmt.Errorf("error saving empty site map file: %v", err) } Defensive patterns
Strategy: retry
Validate before calling
func ensureSitemapWritable(domain string) error {
dir := filepath.Join(PRODUCT_CONFIG_PATH, domain)
if err := os.MkdirAll(dir, 0755); err != nil { return err }
f, err := os.CreateTemp(dir, ".wtest*")
if err != nil { return err }
f.Close(); os.Remove(f.Name())
return nil
}
// call before GetSiteMap on fresh domains Try / catch
m, err := GetSiteMap(domain)
if err != nil && strings.Contains(err.Error(), "error saving empty site map file") {
// create the dir, then retry once
os.MkdirAll(filepath.Join(PRODUCT_CONFIG_PATH, domain), 0755)
m, err = GetSiteMap(domain)
} Prevention
- Create the domain config directory at domain-provisioning time so the bootstrap write always succeeds.
- Keep PRODUCT_CONFIG_PATH on a read-write mount with adequate disk space.
- Fix GetSiteMap itself to MkdirAll before the bootstrap write — the safest guard.
When it happens
Trigger: First call to GetSiteMap (or callers GetSitemap, GetSitemapPrompt, AddSiteMapNode, RemoveSiteMapNode, AppendSitemap) for a domain with no sitemap.json and no PRODUCT_CONFIG_PATH/<domain>/ directory, or with a read-only/non-writable directory.
Common situations: Newly registered domain whose config folder was never created; service user lacks write permission; container volume mounted read-only; PRODUCT_CONFIG_PATH misconfigured to a non-existent base path.
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 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/b53ab425ec300775.
Report an issue: GitHub.