Troubleshooting
Runs and Logs
Section titled “Runs and Logs”View run history
Section titled “View run history”# Last 20 runs (default)db9 functions history my-func --db myapp
# Last 50 runsdb9 functions history my-func --db myapp -n 50
# Specific run detailsdb9 functions history my-func <run_id> --db myapp
# JSON outputdb9 functions history my-func --db myapp --jsonRun record fields
Section titled “Run record fields”| Field | Description |
|---|---|
id | Unique run ID |
status | succeeded or failed |
result_json | Return value (if succeeded) |
error_code | Error type (if failed) |
error_message | Error details (if failed) |
trigger_type | invoke, cron, or api |
started_at | Execution start time |
finished_at | Execution end time |
attempt | Retry attempt number |
version_id | Which version was executed |
View logs
Section titled “View logs”db9 functions logs my-func <run_id> --db myappLogs capture all console.log() and console.error() output from the function.
Error Codes
Section titled “Error Codes”Runtime errors
Section titled “Runtime errors”| Error Code | Cause | Resolution |
|---|---|---|
execution_error | Function threw an exception or returned invalid result | Check error_message and logs for the stack trace |
timeout | Function exceeded timeout_ms limit | Increase timeout or optimize code |
entrypoint_not_found | handler export not found | Use module.exports = { handler: ... } |
SQL errors
Section titled “SQL errors”SQL errors from ctx.db.query() propagate as exceptions:
| Error | Cause |
|---|---|
permission denied for table X | The authenticated role lacks privileges. Run GRANT as admin. |
relation "X" does not exist | Table not found. Check the table name and schema. |
syntax error at or near "..." | Invalid SQL. Check your query string. |
Common Issues
Section titled “Common Issues”Function created but invoke fails
Section titled “Function created but invoke fails”-
Check the run status and error:
Terminal db9 functions history my-func --db myapp -n 1 --json -
Check the logs:
Terminal db9 functions logs my-func <run_id> --db myapp -
Common causes:
execution_error— unhandled exception. Check logs for the stack trace.execution_timeout— increase with--timeout.permission denied for table X— grant access:GRANT ALL ON TABLE X TO authenticated;
”Entrypoint handler is not a function”
Section titled “”Entrypoint handler is not a function””Your code doesn’t export handler as a named property. The runtime expects:
// Correctmodule.exports = { handler: async (input, ctx) => { ... } };
// Wrong — bare function declaration isn't exportedasync function handler(input, ctx) { ... }
// Wrong — module.exports as function (not object with handler key)module.exports = async function handler(input, ctx) { ... };“Unexpected token ‘export’”
Section titled ““Unexpected token ‘export’””The runtime uses CommonJS, not ES modules. export default is a syntax error:
// Wrong — ES module syntax is not supportedexport default async function handler(input, ctx) { ... }
// Correct — use CommonJSmodule.exports = { handler: async (input, ctx) => { ... } };“Unsupported runtime imports detected”
Section titled ““Unsupported runtime imports detected””The CLI detected require() calls that would fail at runtime. This happens when you use:
import somePackage from "package-name"— external npm packages are not availableimport { something } from "./other-file"— multi-file imports are not supported
Bundle your code with esbuild to resolve all imports at build time. See Bundling.
TypeScript transpile fails
Section titled “TypeScript transpile fails”- Ensure your TypeScript syntax is valid
- Use
import type { ... }(notimport { ... }) for type imports - Do not use
importorrequirefor runtime dependencies
Network fetch blocked
Section titled “Network fetch blocked”If fetch() throws EACCES: permission denied ... url not in allowlist, the target URL must be added to the network_allowlist via the REST API.
SQL permission denied
Section titled “SQL permission denied”Functions run as the authenticated role. Tables created by admin need explicit grants:
GRANT ALL ON TABLE my_table TO authenticated;GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO authenticated;Limitations
Section titled “Limitations”| Limitation | Details |
|---|---|
| Single-file deployment | Multi-file imports are not supported. Bundle with esbuild for complex projects. |
| No runtime npm packages | require("axios") fails. Bundle dependencies at build time. |
| TypeScript is transpile-only | No type checking at deploy time. Types are stripped. |
| No persistent state | Each invocation is isolated. Use ctx.db or ctx.fs9 to persist data. |
| Network requires allowlist | fetch() is blocked by default. Configure network_allowlist via REST API. |
| No local emulator | Test by deploying to your database. There is no local dev server. |
| No delete command | Functions cannot be deleted via CLI. Contact support if needed. |
| Authenticated role | Functions run as authenticated, not admin. Grant table access explicitly. |
| Bundle size | Large bundles may hit the proxy body-size limit (413 error). Keep under 5 MB. |
Next Steps
Section titled “Next Steps”- Overview — Quick start and deployment basics
- Runtime & ctx — ctx.db, ctx.fs9, ctx.self API
- Configuration — Secrets, fs9 scope, network, cron, limits
- Examples — Real-world patterns