{"record":{"id":"7eae93c0df3d41d1","repo":"Billionmail/BillionMail","slug":"knowledge-base-file-does-not-exist-s","errorCode":null,"errorMessage":"knowledge base file does not exist: %s","messagePattern":"knowledge base file does not exist: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/askai/project.go","lineNumber":292,"sourceCode":"\t\tif urlsCount > 3 {\n\t\t\treturn fmt.Errorf(\"Add up to 3 URLs\")\n\t\t}\n\t\tconfig.Urls = urls\n\t}\n\n\terr = SaveProjectConfig(Domain, config)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error saving project configuration: %v\", err)\n\t}\n\treturn nil\n}\n\n// ReadKnowledgeBase reads a specific knowledge base from a JSON file based on the provided domain and knowledge ID.\n// It returns a KnowledgeInfo struct or an error if the file does not exist or cannot be\nfunc ReadKnowledgeBase(Domain string, Kid string) (KnowledgeInfo, error) {\n\tfilename := fmt.Sprintf(PRODUCT_CONFIG_PATH+\"/%s/knowledge/%s.json\", Domain, Kid)\n\tif !public.FileExists(filename) {\n\t\treturn KnowledgeInfo{}, fmt.Errorf(\"knowledge base file does not exist: %s\", filename)\n\t}\n\tdata, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn KnowledgeInfo{}, fmt.Errorf(\"error reading knowledge base file: %v\", err)\n\t}\n\n\tvar knowledge KnowledgeInfo\n\terr = json.Unmarshal(data, &knowledge)\n\tif err != nil {\n\t\treturn KnowledgeInfo{}, fmt.Errorf(\"error unmarshalling knowledge base: %v\", err)\n\t}\n\treturn knowledge, nil\n}\n\n// SaveKnowledgeBase saves the provided KnowledgeInfo to a JSON file based on the domain and knowledge ID.\n// It creates the directory if it does not exist and writes the knowledge information to a JSON file\nfunc SaveKnowledgeBase(Domain string, knowledge KnowledgeInfo) error {\n\tknowledgePath := fmt.Sprintf(\"%s/%s/knowledge\", PRODUCT_CONFIG_PATH, Domain)","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/askai/project.go#L274-L310","documentation":"ReadKnowledgeBase builds the path PRODUCT_CONFIG_PATH/<Domain>/knowledge/<Kid>.json and checks existence with public.FileExists before reading. If the file is absent it returns 'knowledge base file does not exist: %s' including the full path. Called by GetKnowledgeBaseList and ModifyKnowledgeBaseFile, this aborts those flows for unknown/missing knowledge entries.","triggerScenarios":"ReadKnowledgeBase(Domain, Kid) where the JSON file for Kid does not exist in the domain's knowledge directory: unknown ID, deleted file, wrong domain, or ID containing path-breaking characters.","commonSituations":"Stale frontend referencing a deleted knowledge base; Kid/domain swapped or truncated (empty Kid produces a directory-like path); case-sensitive filesystem mismatch; domain directory renamed.","solutions":["Confirm the exact file PRODUCT_CONFIG_PATH/<domain>/knowledge/<kid>.json exists on disk","Log/verify the Kid and Domain values reaching ReadKnowledgeBase (no empties or swaps)","Check the filesystem case sensitivity matches the ID casing","List the knowledge directory to see which IDs actually exist","Call os.IsNotExist-style handling in callers to treat this as a 404 rather than a server error"],"exampleFix":"// before\nkb, err := askai.ReadKnowledgeBase(domain, kid)\n// after\nfiles, _ := os.ReadDir(fmt.Sprintf(PRODUCT_CONFIG_PATH+\"/%s/knowledge\", domain))\nfor _, f := range files {\n    if f.Name() == kid+\".json\" {\n        kb, err = askai.ReadKnowledgeBase(domain, kid)\n        break\n    }\n}","handlingStrategy":"type-guard","validationCode":"kbPath := fmt.Sprintf(PRODUCT_CONFIG_PATH+\"/%s/knowledge/%s.json\", domain, kid)\nif !public.FileExists(kbPath) {\n    return ErrKnowledgeNotFound\n}","typeGuard":"func knowledgeExists(domain, kid string) bool {\n    if domain == \"\" || kid == \"\" { return false }\n    return public.FileExists(fmt.Sprintf(PRODUCT_CONFIG_PATH+\"/%s/knowledge/%s.json\", domain, kid))\n}","tryCatchPattern":"kb, err := askai.ReadKnowledgeBase(domain, kid)\nif err != nil && strings.Contains(err.Error(), \"does not exist\") {\n    return respondNotFound(domain, kid)\n} else if err != nil {\n    return err\n}","preventionTips":["Validate kid and domain are non-empty before path construction","List existing knowledge IDs from the directory instead of guessing IDs","Clean up stale frontend references after deletions","Respect filesystem case sensitivity when storing IDs","Treat this error as 404, not 500, in API handlers"],"tags":["go","file-io","knowledge-base"],"backgroundTag":"file-not-found","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}