Skip to content

Commit c3d6305

Browse files
committed
fix(embed): handle absolute file paths from native engine
The native engine stores absolute file paths in the DB. buildEmbeddings unconditionally joined rootDir + file, doubling the path and causing ENOENT for every symbol — producing 0 embeddings silently. Check path.isAbsolute() before joining, and add a regression test that inserts nodes with absolute paths to prevent recurrence. Closes #760
1 parent 4d383bb commit c3d6305

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

src/domain/search/generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export async function buildEmbeddings(
100100
let overflowCount = 0;
101101

102102
for (const [file, fileNodes] of byFile) {
103-
const fullPath = path.join(rootDir, file);
103+
const fullPath = path.isAbsolute(file) ? file : path.join(rootDir, file);
104104
let lines: string[];
105105
try {
106106
lines = fs.readFileSync(fullPath, 'utf-8').split('\n');

tests/search/embedding-strategy.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,47 @@ describe('FTS5 index built alongside embeddings', () => {
289289
});
290290
});
291291

292+
describe('absolute file paths in DB (#760)', () => {
293+
let absDir: string, absDbPath: string;
294+
295+
beforeAll(() => {
296+
absDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-abspath-test-'));
297+
fs.writeFileSync(
298+
path.join(absDir, 'math.js'),
299+
'export function add(a, b) { return a + b; }\n',
300+
);
301+
302+
const absDbDir = path.join(absDir, '.codegraph');
303+
fs.mkdirSync(absDbDir, { recursive: true });
304+
absDbPath = path.join(absDbDir, 'graph.db');
305+
306+
const db = new Database(absDbPath);
307+
db.pragma('journal_mode = WAL');
308+
initSchema(db);
309+
310+
// Insert node with an absolute file path (as the native engine does)
311+
const absFile = path.join(absDir, 'math.js');
312+
insertNode(db, 'add', 'function', absFile, 1, 1);
313+
db.close();
314+
});
315+
316+
afterAll(() => {
317+
if (absDir) fs.rmSync(absDir, { recursive: true, force: true });
318+
});
319+
320+
test('produces embeddings when DB stores absolute paths', async () => {
321+
EMBEDDED_TEXTS.length = 0;
322+
await buildEmbeddings(absDir, 'minilm', absDbPath);
323+
324+
expect(EMBEDDED_TEXTS.length).toBe(1);
325+
326+
const db = new Database(absDbPath, { readonly: true });
327+
const count = db.prepare('SELECT COUNT(*) as c FROM embeddings').get().c;
328+
db.close();
329+
expect(count).toBe(1);
330+
});
331+
});
332+
292333
describe('context window overflow detection', () => {
293334
let bigDir: string, bigDbPath: string;
294335

0 commit comments

Comments
 (0)