Quickback Docs

Troubleshooting

Common issues and solutions when working with the Quickback compiler and generated APIs.

Common issues and their solutions. For cloud compiler specific issues, see Cloud Compiler Troubleshooting.

Compilation Issues

"Feature must use defineTable()"

Your table file is missing the default export:

// Wrong — no default export
export const applications = sqliteTable("applications", { ... });

// Correct — add defineTable default export
export const applications = sqliteTable("applications", { ... });
export default defineTable(applications, { ... });

"File exports multiple tables with defineTable"

A single file can export multiple Drizzle tables, but only ONE can have a defineTable() default export. Split tables into separate files:

quickback/features/applications/
├── applications.ts           # defineTable(applications, { ... })
└── candidates.ts             # defineTable(candidates, { ... })

Missing fields in generated API

If a field exists in your schema but doesn't appear in API responses:

  1. Guards: Check that the field is in createable (for POST) or updatable (for PATCH). Fields not listed are silently stripped.
  2. Views: If using views, the field must be in the view's fields array.
  3. Masking: The field may be present but masked (showing [REDACTED] or ***). Check your masking config.

"organizationId" not auto-injected

The firewall auto-detects organizationId and ownerId columns by name. If your column uses a different name, you need to configure the firewall explicitly:

firewall: {
  organization: { column: "org_id" },  // Custom column name
}

Migration Issues

Columns persist after removal from schema

Quickback (via Drizzle) does not generate DROP COLUMN migrations. If you remove a column from your schema, the database column will remain as an orphaned column. SQLite handles this gracefully — the column won't appear in API responses since Drizzle only selects defined columns.

To clean up, you'd need to manually create a migration.

Drizzle rename prompts in CI

If compilation fails with drizzle-kit requested interactive rename input, add explicit rename hints in your config. See Drizzle rename prompts.

Runtime Issues

401 on all requests

  1. Missing auth: Ensure your request includes Authorization: Bearer <token> or the session cookie
  2. Expired session: Sessions last 7 days by default. Re-authenticate.
  3. Wrong auth URL: Check that BETTER_AUTH_URL matches your deployment URL

403 Forbidden

  1. Wrong role: Check the access config for the endpoint — your role may not be listed
  2. Wrong org: You may be in a different organization than the record's organizationId
  3. Firewall hiding: If errorMode: 'hide' is set, firewall violations return 404 instead of 403

400 Bad Request on create/update

  1. Guard violation: You're sending a field not in createable or updatable. Check the error's details.fields.
  2. Missing required field: A .notNull() column without a default is missing from your request body.
  3. Immutable field: You're trying to update a field marked as immutable.

Records missing from list

Records may be filtered by:

  1. Firewall: Only records matching your organization (and optionally owner) are returned
  2. Soft delete: Soft-deleted records are automatically excluded
  3. Access conditions: Record-level conditions may filter results

See Also

On this page