Summary
A scaffolded service that talks to a database via a native-addon driver crashes on startup under aspire run (and aspire start) because the generated Aspire run command does not grant --allow-ffi. The service exits immediately; any caller (e.g. a Fresh page using @netscript/sdk server-side) then hangs waiting on the dead service.
This bites the SQLite path specifically: Prisma 7 requires a driver adapter (see #173), the Deno-native choice is @prisma/adapter-libsql → @libsql/client, which loads a native .node addon. The same applies to @tursodatabase/database (tursodb) and any native driver.
Environment
- netscript CLI
0.0.1-alpha.12, Aspire CLI 13.4.6, Deno 2.9.0 (Windows x64)
--db sqlite --cache-backend deno-kv, an oRPC --service that constructs a Prisma client (libsql adapter) and/or tursodb.
Error (from the Aspire dashboard resource logs)
[sys] Starting process...: deno run --node-modules-dir=none --allow-net --allow-env --allow-read --allow-sys src/main.ts
error: Uncaught (in promise) NotCapable: Requires ffi access to
"...\@libsql\win32-x64-msvc\0.5.29\index.node", run again with the --allow-ffi flag
at requireNative (.../libsql/0.5.29/index.js:26:10)
Root cause
aspire/.helpers/register-services.mts (generated) builds each service with a hardcoded permission set and no --allow-ffi:
const perms = resolvePermissions(
undefined,
["--allow-net","--allow-env","--allow-read","--allow-sys"], // <- no --allow-ffi
false, '--watch-hmr',
);
builder.addExecutable('eischat', 'deno', workdir,
['run', '--node-modules-dir=none', ...perms, 'src/main.ts'])
resolvePermissions(entryPermissions, defaults, …) supports an entryPermissions override, but the generated call passes undefined, and there is no config knob (nothing in appsettings.json / config-schema.mts) to add permissions per service.
It works with deno task --cwd services/<svc> dev only because that task uses -A.
Cascade (why it looks like "service discovery")
Service dead → a dashboard page's server-side serviceClient.list() hangs (60s) → HTTP 000. The scaffold's own routes/examples/eischat page hangs identically, while /health is 200. Easy to misdiagnose as SDK/URL resolution; the Aspire dashboard/MCP resource logs show the real NotCapable crash.
Fix (validated)
Add --allow-ffi to the service perms. After this, the service boots, channel RPC returns, and the dashboard page renders HTTP 200.
Suggestions:
- Grant
--allow-ffi to services by default (or when a native-addon DB dep is detected), and/or
- Expose a per-service permissions knob in
appsettings.json (NetScript.Services.<name>.Permissions / DenoArgs) that flows into resolvePermissions(entryPermissions, …) instead of the hardcoded undefined.
Happy to PR the --allow-ffi change (and a perms config knob). Two unrelated log-noise items observed on the same service are filed separately (spurious MySQL probe under --db sqlite; Deno.serve legacy-abort deprecation).
Found while integration-testing the SQLite path for a Netscript app (eis-chat), companion to #173. Filed by Claude (Opus) with @rickylabs.
Summary
A scaffolded service that talks to a database via a native-addon driver crashes on startup under
aspire run(andaspire start) because the generated Aspire run command does not grant--allow-ffi. The service exits immediately; any caller (e.g. a Fresh page using@netscript/sdkserver-side) then hangs waiting on the dead service.This bites the SQLite path specifically: Prisma 7 requires a driver adapter (see #173), the Deno-native choice is
@prisma/adapter-libsql→@libsql/client, which loads a native.nodeaddon. The same applies to@tursodatabase/database(tursodb) and any native driver.Environment
0.0.1-alpha.12, Aspire CLI13.4.6, Deno2.9.0(Windows x64)--db sqlite --cache-backend deno-kv, an oRPC--servicethat constructs a Prisma client (libsql adapter) and/or tursodb.Error (from the Aspire dashboard resource logs)
Root cause
aspire/.helpers/register-services.mts(generated) builds each service with a hardcoded permission set and no--allow-ffi:resolvePermissions(entryPermissions, defaults, …)supports anentryPermissionsoverride, but the generated call passesundefined, and there is no config knob (nothing inappsettings.json/config-schema.mts) to add permissions per service.It works with
deno task --cwd services/<svc> devonly because that task uses-A.Cascade (why it looks like "service discovery")
Service dead → a dashboard page's server-side
serviceClient.list()hangs (60s) →HTTP 000. The scaffold's ownroutes/examples/eischatpage hangs identically, while/healthis200. Easy to misdiagnose as SDK/URL resolution; the Aspire dashboard/MCP resource logs show the realNotCapablecrash.Fix (validated)
Add
--allow-ffito the service perms. After this, the service boots, channel RPC returns, and the dashboard page rendersHTTP 200.Suggestions:
--allow-ffito services by default (or when a native-addon DB dep is detected), and/orappsettings.json(NetScript.Services.<name>.Permissions/DenoArgs) that flows intoresolvePermissions(entryPermissions, …)instead of the hardcodedundefined.Happy to PR the
--allow-ffichange (and a perms config knob). Two unrelated log-noise items observed on the same service are filed separately (spurious MySQL probe under--db sqlite;Deno.servelegacy-abort deprecation).Found while integration-testing the SQLite path for a Netscript app (eis-chat), companion to #173. Filed by Claude (Opus) with @rickylabs.