Billionmail/BillionMail · error
error unmarshalling knowledge base: %v
Error message
error unmarshalling knowledge base: %v
What it means
After a successful read, ReadKnowledgeBase unmarshals the bytes into a KnowledgeInfo struct. Malformed or schema-incompatible JSON yields 'error unmarshalling knowledge base: %v' with the encoding/json cause. The file exists and was readable, but its contents cannot be represented as KnowledgeInfo.
Source
Thrown at core/internal/service/askai/project.go:302
return nil
}
// ReadKnowledgeBase reads a specific knowledge base from a JSON file based on the provided domain and knowledge ID.
// It returns a KnowledgeInfo struct or an error if the file does not exist or cannot be
func ReadKnowledgeBase(Domain string, Kid string) (KnowledgeInfo, error) {
filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/knowledge/%s.json", Domain, Kid)
if !public.FileExists(filename) {
return KnowledgeInfo{}, fmt.Errorf("knowledge base file does not exist: %s", filename)
}
data, err := os.ReadFile(filename)
if err != nil {
return KnowledgeInfo{}, fmt.Errorf("error reading knowledge base file: %v", err)
}
var knowledge KnowledgeInfo
err = json.Unmarshal(data, &knowledge)
if err != nil {
return KnowledgeInfo{}, fmt.Errorf("error unmarshalling knowledge base: %v", err)
}
return knowledge, nil
}
// SaveKnowledgeBase saves the provided KnowledgeInfo to a JSON file based on the domain and knowledge ID.
// It creates the directory if it does not exist and writes the knowledge information to a JSON file
func SaveKnowledgeBase(Domain string, knowledge KnowledgeInfo) error {
knowledgePath := fmt.Sprintf("%s/%s/knowledge", PRODUCT_CONFIG_PATH, Domain)
if !public.FileExists(knowledgePath) {
os.MkdirAll(knowledgePath, os.ModePerm)
}
filename := fmt.Sprintf("%s/%s.json", knowledgePath, knowledge.Kid)
configStr, err := json.MarshalIndent(knowledge, "", " ")
if err != nil {
return fmt.Errorf("error marshalling knowledge base: %v", err)
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Validate the file with jq (or json.Unmarshal in a scratch test) to see the exact syntax/type error
- Compare file contents against the current KnowledgeInfo struct field types
- Re-save the knowledge entry (or delete it) via SaveKnowledgeBase to regenerate valid JSON
- Make saves atomic (write temp file + os.Rename) to prevent truncation
- Inspect the wrapped json error (offset/type mismatch) to locate the bad field
Example fix
// before
kb, err := askai.ReadKnowledgeBase(domain, kid)
// after
kb, err := askai.ReadKnowledgeBase(domain, kid)
if err != nil && strings.Contains(err.Error(), "unmarshalling") {
os.Remove(fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/knowledge/%s.json", domain, kid))
return fmt.Errorf("corrupt knowledge %s removed: %w", kid, err)
} Defensive patterns
Strategy: validation
Validate before calling
data, err := os.ReadFile(fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/knowledge/%s.json", domain, kid))
if err != nil { return err }
var probe askai.KnowledgeInfo
if err := json.Unmarshal(data, &probe); err != nil {
return fmt.Errorf("corrupt knowledge file: %w", err)
} Type guard
func validKnowledgeJSON(data []byte) bool {
var k askai.KnowledgeInfo
return json.Unmarshal(data, &k) == nil
} Try / catch
kb, err := askai.ReadKnowledgeBase(domain, kid)
if err != nil && strings.Contains(err.Error(), "unmarshalling knowledge base") {
log.Printf("corrupt knowledge %s/%s: %v", domain, kid, err)
return respondConflict("knowledge entry is corrupt; re-save it")
} Prevention
- Always write knowledge files atomically (temp + rename)
- Run json.Unmarshal validation after every save
- Version the KnowledgeInfo schema and migrate old files
- Reject non-JSON uploads regardless of extension
- Include the json offset/type error from the wrapped cause in logs
When it happens
Trigger: ReadKnowledgeBase(Domain, Kid) where the JSON file exists and reads fine but json.Unmarshal fails: truncated file, invalid syntax, or fields with wrong types (e.g. string where KnowledgeInfo expects a number/array).
Common situations: Partial write from a crashed SaveKnowledgeBase (no atomic rename); manual editing that broke JSON syntax; KnowledgeInfo struct fields changed in a code update so old files no longer decode; non-JSON content saved under a .json name.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- failed to unmarshal tool call arguments: %v, %s
- error unmarshalling project configuration: %v
- error marshalling project configuration: %v
- error getting knowledge base list: %v
- knowledge base file does not exist: %s
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/8ab25ac07e23ba1d.
Report an issue: GitHub.