{"record":{"id":"6922532ba62a07b1","repo":"NationalSecurityAgency/ghidra","slug":"elasticsearch-database-does-not-have-callgraph-inf","errorCode":null,"errorMessage":"Elasticsearch database does not have callgraph information enabled","messagePattern":"Elasticsearch database does not have callgraph information enabled","errorType":"validation","errorClass":"ElasticException","httpStatus":null,"severity":"warning","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java","lineNumber":3509,"sourceCode":"\t\tJsonObject source = (JsonObject) resp.get(\"_source\");\n\t\tJsonArray childid = (JsonArray) source.get(\"childid\");\n\t\treturn childid;\n\t}\n\n\t/**\n\t * Given a specific function, query for all of its child functions.\n\t * Uses a RowKey->FunctionDescription map to cache functions and avoid\n\t * querying for the same function multiple times\n\t * @param funcRecord is the specified function\n\t * @param manager is the container for new child FunctionDescriptions\n\t * @param functionMap is the cache\n\t * @throws ElasticException for communication problems with the server\n\t * @throws LSHException for problems adding records to the container\n\t */\n\tprivate void fillinChildren(FunctionDescription funcRecord, DescriptionManager manager,\n\t\t\tMap<RowKey, FunctionDescription> functionMap) throws ElasticException, LSHException {\n\t\tif (!info.trackcallgraph) {\n\t\t\tthrow new ElasticException(\n\t\t\t\t\"Elasticsearch database does not have callgraph information enabled\");\n\t\t}\n\t\tJsonArray callids = queryCallgraphRows(funcRecord);\n\t\tif (callids == null) {\n\t\t\treturn;\t\t// field is not present, meaning children are not present\n\t\t}\n\t\tfor (JsonElement callid : callids) {\n\t\t\tString funcId = callid.getAsString();\n\t\t\tRowKeyElastic eKey = RowKeyElastic.parseFunctionId(funcId);\n\t\t\tFunctionDescription fdesc = functionMap.get(eKey);\n\t\t\tif (fdesc == null) {\n\t\t\t\tfdesc = querySingleDescriptionId(manager, funcId);\n\t\t\t\tfunctionMap.put(eKey, fdesc);\n\t\t\t}\n\t\t\tmanager.makeCallgraphLink(funcRecord, fdesc, 0);\n\t\t}\n\t}\n","sourceCodeStart":3491,"sourceCodeEnd":3527,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java#L3491-L3527","documentation":"Thrown by ElasticDatabase.fillinChildren when asked to expand the children of a function but the database's DatabaseInformation.trackcallgraph flag is false. trackcallgraph is a per-database attribute fixed at initialization/ingest time; when false the index never stored callgraph edges, so child expansion is impossible. This guard sits inside the internal recursion path (distinct from the command-level check in fdbQueryChildren).","triggerScenarios":"Any code path that drives fillinChildren on a database created with trackcallgraph=false — typically a query that internally traverses callgraph edges (overview/nearest with child expansion) without first checking the capability.","commonSituations":"Database initialized with trackcallgraph=false (either explicitly or via an older initialize config) and then queried with a callgraph-dependent operation; mixing an old DB created before callgraph tracking against a newer client that assumes it.","solutions":["Inspect database.getInfo().trackcallgraph before invoking any callgraph-expanding query and disable that UI/code path when false.","Re-create or re-initialize the Elasticsearch BSim database with trackcallgraph=true and re-ingest executables.","If you only need similarity (not call edges), use a non-callgraph query path so fillinChildren is never reached."],"exampleFix":"// before\nfillinChildren(element, response.manage, funcmap);\n// after\nif (database.getInfo().trackcallgraph) {\n    fillinChildren(element, response.manage, funcmap);\n}","handlingStrategy":"validation","validationCode":"DatabaseInformation info = database.getInfo();\nif (!info.trackcallgraph) {\n    // disable child-expansion UI/code path\n    return;\n}","typeGuard":"static boolean supportsCallgraph(FunctionDatabase db) {\n    DatabaseInformation info = db.getInfo();\n    return info != null && info.trackcallgraph;\n}","tryCatchPattern":"if (!database.getInfo().trackcallgraph) {\n    // skip callgraph expansion gracefully\n} else {\n    fillinChildren(element, manager, functionMap);\n}","preventionTips":["Check database.getInfo().trackcallgraph once at connect time and cache the capability for UI gating.","When creating a database you may later query for children, always initialize with trackcallgraph=true.","Document per-database capabilities in your connection metadata so the UI can hide unsupported actions."],"tags":["bsim","elasticsearch","callgraph","configuration","capability"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}