Troubleshooting
Common issues and their solutions, organized by category.
Installation & Startup
npm install fails with peer dependency errors
Next.js 16 and React 19 are still relatively new. Some packages may report peer dependency warnings. In most cases these are harmless. If the install fails entirely:
npm install --legacy-peer-depsconfig.json not found
The application requires a config.json in the project root. If it is missing, you will see an
error on startup. Copy the template:
cp config.template.json config.jsonThen adjust the casesDirectory path to point to your case data folder.
Port 3000 already in use
Another process is using port 3000. Either stop it or start Next.js on a different port:
npm run dev -- -p 3001Solver Connection
”Solver not configured” message
This means staffSchedulingProject.include is set to false in config.json. To enable solver
integration:
{
"staffSchedulingProject": {
"include": true,
"path": "/absolute/path/to/StaffScheduling",
"pythonExecutable": "uv"
}
}Make sure the path points to the root of the StaffScheduling Python project.
Solver health check fails
On the Solver page, the application validates that the solver is reachable. If this check fails:
- CLI mode: Verify that
python(oruv) is available in your system PATH and that the StaffScheduling project is installed (uv syncin the solver project directory). - API mode: Ensure the FastAPI server is running:
The server should be reachable at
cd /path/to/StaffScheduling uv run staff-scheduling-apihttp://127.0.0.1:8000. Verify with:curl http://127.0.0.1:8000/status
Solve returns “INFEASIBLE”
The solver could not find any valid schedule with the current constraints. This typically means:
- Minimum staffing requirements are too high for the number of available employees. Reduce values on the Minimum Staff page.
- Too many blocked days leave insufficient scheduling flexibility. Review blocked days on the Wishes & Blocked page.
- Vacation days and forbidden days cover too much of the month. Check
free_shifts_and_vacation_days.jsonfor unexpected entries.
Try temporarily lowering minimum staff requirements to confirm feasibility, then incrementally increase them.
Solve runs but produces poor quality schedules
- Increase the timeout. The default is 5 minutes (300 seconds). The solver improves solutions over time — a longer timeout often yields significantly better results.
- Adjust weights. If a specific metric is too high (e.g. overtime), increase its weight in the Weights configuration. Higher weights cause the solver to prioritize that objective.
- Use Solve Multiple. The three built-in weight presets (Default, Balanced, Staff Focus) often produce at least one good variant.
Data & Cases
Case selector is empty
No case directories were found at the configured casesDirectory path. Verify:
- The path in
config.jsonis correct (absolute or relative to project root). - The directory contains at least one subdirectory with the structure
<caseId>/<MM_YYYY>/. - The application has read permissions on the directory.
Employee list is empty after selecting a case
The employees.json file is missing or empty for the selected case and month. This file is
generated by the StaffScheduling fetch command. Either:
- Run Fetch from the Solver page or Workflow to pull data from TimeOffice.
- Manually place an
employees.jsonfile in the case directory (see Underlying Data).
Changes to wishes are not reflected in the schedule
Wishes are read by the solver at solve time. After modifying wishes, you must re-run the solver to generate a new schedule that incorporates the changes. Existing schedules are not retroactively updated.
Global wishes overwrite monthly wishes
This is expected behavior. Saving or modifying a global wish for an employee deletes and regenerates all monthly entries for that employee. Always configure global wishes first, then add monthly adjustments on top. See the User Guide for the recommended workflow.
Schedule View
Schedule table is empty after solving
After a successful solve, the application prompts you to import the result. If you navigated away from the page before confirming, the schedule was not imported. You can recover it:
- Navigate to the Schedule page.
- Click Upload and browse to the solver’s
processed_solutions/directory. - Select the
processed_solution_*.jsonfile matching your solve run.
Wish/blocked symbols are not visible in the schedule
The schedule view overlays wish and blocked indicators on shift cells. These symbols may not be visible if:
- No wishes or blocked entries exist for the current case/month.
- The schedule was imported from an external source without corresponding wish data.
Development
TypeScript compilation errors after adding a new feature
Run through the Completion Checklist in the Developer Guide. Common causes:
- Missing
DI_SYMBOLSorDI_RETURN_TYPESentries indi/types.ts. - Module not loaded in
di/container.ts. - Import from a forbidden layer (e.g. infrastructure imported in a use case).
Server Action returns “error” but no details
Controllers catch DomainError instances and convert them to { error: string }. If you see a
generic error, the thrown error may not extend DomainError. Ensure all custom errors in
src/entities/errors/ inherit from the DomainError base class.
LowDB file is corrupted or has unexpected content
LowDB writes are not atomic. If the application crashes during a write, the JSON file may be incomplete. To recover:
- Check if a backup exists (LowDB does not create backups by default).
- Delete the corrupted file — the application will recreate it with defaults on next access.
- If the file contained important data (e.g. schedules), re-import from the solver output.
CI/CD
CI check fails on push
The GitHub Actions pipeline (ci-check.yml) runs two parallel jobs on every push:
- Lint —
npm run lint(ESLint with core-web-vitals + TypeScript rules) - Build —
npm run build(full Next.js production build)
Fix lint errors locally before pushing:
npm run lint
npx tsc --noEmitDocumentation not updating on GitHub Pages
The docs workflow (docs.yml) only triggers on pushes to main that modify files in the docs/
directory. If your documentation changes are on a different branch, merge to main first.