Skip to content

surrealkv:// close() does not release file lock, causing subsequent connect() to deadlock #592

@nerdo

Description

@nerdo

Summary

When using @surrealdb/node@3.0.3 with surrealdb@2.0.3, calling close() on a surrealkv:// connection does not release the file-level LOCK. A subsequent connect() to the same file hangs indefinitely.

Reproduction

import { Surreal } from "surrealdb";
import { createNodeEngines } from "@surrealdb/node";

const url = "surrealkv:///tmp/test-lock-bug.db";

// First connection — works fine
const db1 = new Surreal({ engines: createNodeEngines() });
await db1.connect(url);
await db1.use({ namespace: "test", database: "test" });
console.log("First connected.");

await db1.close();
console.log("First closed.");

// Second connection — hangs forever
const db2 = new Surreal({ engines: createNodeEngines() });
await db2.connect(url); // ← never resolves
console.log("Second connected."); // ← never reached

Run with: bun -e '<above>' (or npx tsx)

Expected behavior

After close(), the LOCK file should be released and a new connect() to the same surrealkv:// path should succeed.

Actual behavior

The second connect() hangs indefinitely. A LOCK file remains in the database directory after close():

$ ls /tmp/test-lock-bug.db/
LOCK  manifest/  sstables/  vlog/  wal/

Reproduced consistently (3/3 attempts, fresh database paths each time).

Environment

  • @surrealdb/node: 3.0.3
  • surrealdb (JS SDK): 2.0.3
  • Runtime: Bun 1.3.11 (macOS arm64, Darwin 25.3.0)
  • Also reproducible pattern: any code that opens sequential connections to the same surrealkv:// file (e.g., connection pooling, service restart, database migration scripts)

Workaround

Use a single shared connection for the lifetime of the process instead of opening/closing connections. The embedded surrealkv engine reflects data changes immediately through an existing connection, so reconnection is unnecessary for data freshness. However, this prevents use cases like connection health recovery or graceful restart.

Notes

  • mem:// connections do not exhibit this behavior — only surrealkv:// file-backed databases
  • The issue does not occur with @surrealdb/node@2.3.5 — it appears to be a regression in v3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions