Skip to content
Documentation GitHub
Development Guides

Debug Common Issues

Quick fixes for frequently encountered problems.


Build Errors

Linter issues (oxlint)

Symptom: Unexpected lint errors or warnings when running pnpm lint.

Cause: The project uses oxlint (not ESLint) for TypeScript linting. oxlint is faster but has a different rule set and configuration model.

Fix:

Common quick checks:

  • Confirm you are running pnpm lint from the repo root (not a subdirectory)
  • Confirm node_modules is populated (pnpm install)
  • Use /* oxlint-disable */ comments (not eslint-disable) for lint suppression
  • Run ./tools/precheck.sh --fix to auto-fix formatting and linting issues

Clippy idiom errors

Symptom: cargo clippy or the pre-commit hook reports clippy warnings that are not obvious from the code (e.g., clone_on_copy, needless_pass_by_ref_mut, large_enum_variant).

Fix: See docs/solutions/build-errors/rust-clippy-idioms-catalog.md for a catalog of common patterns and their fixes.

The pre-commit hook runs gitleaks only. For clippy and other lint checks, run the quality gate:

Terminal window
./tools/precheck.sh # scoped to changed files vs main (check only)
./tools/precheck.sh --fix # auto-fix formatting/linting, then check
./tools/precheck.sh --no-test # skip cargo test

A common false positive: #[tool_handler] or #[derive(FromRequest)] macros generate runtime dispatch code invisible to clippy, which then reports dead_code on the variants they dispatch. Use a targeted #[allow(dead_code)] with a comment naming the macro. See docs/solutions/build-errors/proc-macro-dead-code-false-positives.md.


TypeScript type errors after Rust struct changes

Symptom: TypeScript fails with “cannot find name” or type mismatch errors on types from packages/contracts/generated/.

Cause: The generated bindings are stale. They are produced by Specta from Rust structs via #[specta::specta] annotations.

Fix:

Terminal window
pnpm generate:types

Run this any time you add, remove, or rename a field on a Rust type that has #[derive(specta::Type)]. The output goes to packages/contracts/generated/bindings.ts — do not edit this file by hand.

Note on casing: Specta preserves Rust snake_case field names in TypeScript output. storage_path generates as storage_path, not storagePath. Don’t assume camelCase conversion.


Runtime Errors

”Database version is newer than app version”

Symptom: The app shows an error about the workspace database version being ahead of the app.

Cause: The workspace was created by a newer build (e.g., switching branches after running migrations).

Fix: Reset dev data:

Terminal window
./tools/dev/reset-app-data.sh # interactive
./tools/dev/reset-app-data.sh --force # skip confirmation

This clears .data/ (dev workspaces and settings). Production data at ~/Inklings/ is never touched.


MCP server won’t start

Symptom: MCP status shows “not running” despite being enabled in settings.

Common causes:

  1. Port conflict: Something else is already on port 7862:

    Terminal window
    lsof -i :7862

    Change the MCP port in app settings, or kill the conflicting process.

  2. No workspace open: The MCP server starts only when a workspace is open. Open a workspace first.

  3. Feature not enabled: Confirm mcp_enabled is true in settings (Settings → Developer → MCP Server).


Test Failures

Integration test isolation

Symptom: An integration test passes alone but fails when run alongside others. Or: a test passes on the first run but fails on subsequent runs without code changes.

Cause: SQLite integration tests (tests/core/) use TempDir for isolation, but if a test panics before cleanup, the temp directory may persist.

Fix: Each TestWorkspace::new() call creates a fresh temporary directory. Tests that share a TestWorkspace must not rely on execution order. If a test is modifying shared state, verify it uses its own TestWorkspace instance.

For FK constraint failures: verify that pages referenced as parents exist before calling create_batch. Filter orphan parent_slug values in fixture data.


Playwright setup: “browser not installed”

Symptom: Playwright tests fail immediately with a message about the browser binary not being found.

Fix:

Terminal window
cd apps/desktop/tests
pnpm exec playwright install

Or for E2E:

Terminal window
cd tests/e2e
pnpm exec playwright install

Playwright browsers are not installed by pnpm install — they require a separate step.


Playwright test timing out

Symptom: A test passes locally but times out in CI, or passes intermittently.

Checks:

  1. Increase the timeout for the specific assertion:

    await expect(element).toBeVisible({ timeout: 10000 });
  2. Use waitForAppReady(page) before any assertions — it waits for the sidebar to be visible, which confirms the app has loaded.

  3. For E2E tests: CI runs with workers: 1 (sequential). If a test assumes a specific page ordering that varies with parallel execution, it may fail only in CI.


Selector not found in Playwright tests

Symptom: Playwright cannot locate an element that is visible in the running app.

Approach:

  1. Run in headed mode to see the actual DOM:

    Terminal window
    pnpm --dir apps/desktop/tests test:headed
  2. Use Playwright UI mode to interactively explore elements:

    Terminal window
    pnpm --dir apps/desktop/tests test:ui
  3. Prefer role-based selectors (getByRole, getByText) over data-testid attributes. Role-based selectors are more resilient to DOM restructuring.

  4. For E2E: check tests/e2e/seed.spec.ts to understand what the appPage fixture sets up before your test runs.


Development Environment

Dev data reset

Clear all app state for the current development environment (workspaces, settings):

Terminal window
./tools/dev/reset-app-data.sh # interactive, asks for confirmation
./tools/dev/reset-app-data.sh --force # no confirmation

This only clears .data/ (the dev environment directory). It never touches:

  • ~/Inklings/ (production workspaces)
  • ~/Library/Application Support/Inklings/ (production settings)

After resetting, the app treats the next launch as a first run and shows the onboarding tour.


Type generation issues

If pnpm generate:types fails or produces unexpected output:

  1. Build error in src-tauri: Fix any Rust compile errors first — type generation compiles the Tauri app.

  2. Stale generated file: Delete packages/contracts/generated/bindings.ts and re-run pnpm generate:types.

  3. Changed struct fields: After adding fields to a Rust type that derives specta::Type, run pnpm generate:types and commit the updated bindings.ts. The TypeScript frontend will immediately see the new fields.

  4. Missing #[specta::specta] on a new command: If a new Tauri command is missing the #[specta::specta] attribute, it will not appear in bindings.ts. Add the attribute and re-run type generation.


Pre-commit hook failures

Symptom: git commit is rejected by the pre-commit hook.

The pre-commit hook runs gitleaks only (secret scanning). Formatting and linting are not enforced at commit time.

Common fixes:

  • gitleaks failure: A staged file contains a string that looks like a secret. Review the flagged file. If it is a false positive, use gitleaks --baseline-path or add an allowlist entry.

For formatting and linting issues, run the quality gate before committing:

Terminal window
./tools/precheck.sh --fix # auto-fix formatting/linting, then validate

See Also

  • Full solution docs: docs/solutions/
  • Build errors specifically: docs/solutions/build-errors/
  • Database patterns: docs/solutions/database-issues/
  • Architecture decisions: docs/ADR/

Was this page helpful?