{"record":{"id":"d695a9a5ae5f91e3","repo":"tursodatabase/turso","slug":"unknown-error-type-name-from-turso-d695a9","errorCode":null,"errorMessage":"unknown error type ${name} from Turso","messagePattern":"unknown error type (.+?) from Turso","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/javascript/packages/common/promise.ts","lineNumber":23,"sourceCode":"\nconst convertibleErrorTypes = { TypeError };\nconst CONVERTIBLE_ERROR_PREFIX = \"[TURSO_CONVERT_TYPE]\";\n\nfunction convertError(err) {\n  if ((err.code ?? \"\").startsWith(CONVERTIBLE_ERROR_PREFIX)) {\n    return createErrorByName(\n      err.code.substring(CONVERTIBLE_ERROR_PREFIX.length),\n      err.message,\n    );\n  }\n\n  return new SqliteError(err.message, err.code, err.rawCode);\n}\n\nfunction createErrorByName(name, message) {\n  const ErrorConstructor = convertibleErrorTypes[name];\n  if (!ErrorConstructor) {\n    throw new Error(`unknown error type ${name} from Turso`);\n  }\n\n  return new ErrorConstructor(message);\n}\n\n// The engine returned STEP_SLEEP: its busy handler wants the statement retried\n// after a backoff delay. Park the step loop on a timer promise — unlike STEP_IO\n// there is no I/O completion coming to wake us up, so waiting on the IO\n// notifier would hang (WASM) or spin (native).\nfunction sleepBeforeRetry(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction isQueryOptions(value) {\n  return value != null\n    && typeof value === \"object\"\n    && !Array.isArray(value)\n    && Object.prototype.hasOwnProperty.call(value, \"queryTimeout\");","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/javascript/packages/common/promise.ts#L5-L41","documentation":"This is the async (promise-based) layer's copy of the error-conversion logic in the Turso JavaScript bindings. When a rejected native error carries a code prefixed with '[TURSO_CONVERT_TYPE]', the JS layer maps the trailing name to a registered constructor via convertibleErrorTypes (currently only TypeError). An unregistered name makes createErrorByName throw this 'unknown error type' Error, replacing the original failure. It signals a version skew between the native module and the JS packages, or a library bug - not a caller mistake.","triggerScenarios":"An async call (client.execute, db.prepare in promise.ts, batch, or any await on the promise facade) rejects with err.code = '[TURSO_CONVERT_TYPE]<Name>' where <Name> is not 'TypeError'. Occurs when the native artifact and packages/common are built from different revisions, or a new convertible type was added natively without updating the registry at promise.ts.","commonSituations":"Partial upgrades where @tursodb/native-* and the JS packages come from different releases; custom WASM builds of the native layer; lockfiles resolving mismatched versions after a branch switch; nightly/canary native builds paired with stable JS packages.","solutions":["Align versions: update the native module and all @tursodb JS packages to the same release in one install","Nuke stale artifacts: rm -rf node_modules && npm install (or cargo clean for local native builds) to rebuild both halves consistently","Verify with a trivial await client.execute('SELECT 1') after realignment to confirm error plumbing is healthy","If it persists on matched versions, capture the reported type name and open an upstream issue - the registry is missing it"],"exampleFix":"// before: native@2.1.0 emits [TURSO_CONVERT_TYPE]RangeError, js@2.0.0 only knows TypeError\nawait client.execute('SELECT 1'); // -> Error: unknown error type RangeError from Turso\n\n// after: pin both to the same version in package.json\n// \"@tursodb/client\": \"2.1.0\", \"@tursodb/native-*\": \"2.1.0\"","handlingStrategy":"try-catch","validationCode":"// No pre-call validation exists: the failure is internal to error conversion.\n// At startup, verify the native and JS halves come from one release:\nconsole.assert(pkgVersionsMatch(), 'native/JS binding version skew detected');","typeGuard":"function isTursoConversionError(err: unknown): boolean {\n  return err instanceof Error && /^unknown error type .+ from Turso$/.test(err.message);\n}","tryCatchPattern":"try {\n  const rs = await client.execute(sql);\n} catch (err) {\n  if (isTursoConversionError(err)) {\n    // Version skew / library bug: escalate, never mask the underlying failure with a retry\n    telemetry.report('binding-version-skew', { message: err.message });\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Pin native and JS packages to identical versions and update them atomically","Include an error-path smoke test (a statement that must fail, e.g. bad SQL) in CI to catch conversion regressions","Never silently swallow this error - it hides the real database failure underneath"],"tags":["turso","javascript","async","bindings","error-conversion","version-mismatch"],"backgroundTag":"unknown-error-code-mapping","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}