Billionmail/BillionMail · error

error saving knowledge base: %v

Error message

error saving knowledge base: %v

What it means

After reading and mutating the KnowledgeInfo (title/content/update time), ModifyKnowledgeBaseFile persists it via SaveKnowledgeBase. This error wraps any SaveKnowledgeBase failure — marshalling or, far more commonly, writing the JSON file. The read succeeded but the save failed, so the update was not persisted.

Source

Thrown at core/internal/service/askai/project.go:398

// If the knowledge base does not exist or cannot be read, it returns an error.
func ModifyKnowledgeBaseFile(Domain string, Kid string, Title string, Content string) error {
	knowledge, err := ReadKnowledgeBase(Domain, Kid)
	if err != nil {
		return fmt.Errorf("error reading knowledge base: %v", err)
	}

	// Update the knowledge base information
	if Title != "" {
		knowledge.Title = Title
	}
	if Content != "" {
		knowledge.Content = Content
	}

	knowledge.UpdateTime = public.GetNowTime()
	err = SaveKnowledgeBase(Domain, knowledge)
	if err != nil {
		return fmt.Errorf("error saving knowledge base: %v", err)
	}
	return nil
}

// RemoveKnowledgeBaseFile removes a knowledge base file based on the provided domain and knowledge ID.
// It constructs the file path, checks if the file exists, and removes it.
func RemoveKnowledgeBaseFile(Domain string, Kid string) error {
	filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/knowledge/%s.json", Domain, Kid)
	if !public.FileExists(filename) {
		return fmt.Errorf("knowledge base file does not exist: %s", filename)
	}
	err := os.Remove(filename)
	if err != nil {
		return fmt.Errorf("error removing knowledge base file: %v", err)
	}
	return nil
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Read the wrapped inner error ('error writing knowledge base file' vs 'error marshalling knowledge base') to isolate the cause
  2. Check write permissions and disk space for PRODUCT_CONFIG_PATH/<domain>/knowledge
  3. Ensure the service user can overwrite the existing <kid>.json file (chown/chmod)
  4. Verify Domain/Kid contain no invalid path characters

Example fix

// before
err = os.WriteFile(filename, configStr, os.ModePerm)
// after
if err := os.WriteFile(filename, configStr, 0o644); err != nil {
    return fmt.Errorf("error writing knowledge base file %s: %w", filename, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if err := canWriteKnowledgeDir(domain); err != nil {
    return fmt.Errorf("cannot persist knowledge base: %w", err)
}
if !knowledgeBaseExists(domain, kid) {
    return fmt.Errorf("knowledge base %s not found", kid)
}

Try / catch

if err := ModifyKnowledgeBaseFile(domain, kid, title, content); err != nil {
    if strings.Contains(err.Error(), "saving knowledge base") {
        log.Errorf("Update not persisted for %s/%s: %v", domain, kid, err)
        // retry or surface write-failure to the API caller
    }
}

Prevention

When it happens

Trigger: SaveKnowledgeBase fails while writing <kid>.json: parent directory missing/unwritable (MkdirAll error ignored), permission denied on the file, disk full, or Kid path characters creating an invalid path.

Common situations: Read-only volume or full disk at write time; ownership mismatch (file created by root, service now running as another user); PRODUCT_CONFIG_PATH config drift between processes; Kid containing path separators.

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


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/c990e5e4a8eab9f8. Report an issue: GitHub.