Troubleshooting
This page helps diagnose common problems when working with application modules. Most issues come from one of a few places: the project was not initialized for modules, the module exists on disk but is not declared in vix.app, a module is disabled, a dependency is missing, a route prefix is duplicated, or a public header is reaching into private implementation files.
Start with the module check command. It gives a clearer signal than waiting for a compiler error from generated files or indirect includes.
vix modules checkFor module-based backends, the normal local workflow is:
vix modules check
vix build2
When tests are part of the validation, run:
vix modules check
vix check --tests --run2
modules/ folder not found
If the module command reports that the modules/ folder is missing, the project has not been initialized for application modules yet.
Run the initialization command from the project root.
vix modules initThis creates:
modules/
cmake/vix_modules.cmake2
In a vix.app project, Vix uses this module loader from the generated application build. In a CMake-first project, the loader can be included from the root CMakeLists.txt.
Module already exists
If vix modules add auth reports that the module already exists, Vix found a folder at:
modules/auth/This usually means the module was already created, copied from another branch, or partially generated during an earlier attempt.
Check the folder first.
ls modules/authA simple module should contain files such as:
include/auth/api.hpp
src/auth.cpp
tests/test_auth.cpp
CMakeLists.txt
vix.module2
3
4
5
A backend module should contain files such as:
include/auth/AuthModule.hpp
include/auth/controllers/AuthController.hpp
src/AuthModule.cpp
src/controllers/AuthController.cpp
tests/test_auth.cpp
CMakeLists.txt
vix.module2
3
4
5
6
7
If the folder is valid, do not recreate it. Register it in vix.app when the project uses the manifest workflow.
[module.auth]
enabled = true
path = "modules/auth"
kind = "backend"
depends = []2
3
4
5
Then run:
vix modules checkModule folder exists but is not declared
In a vix.app project, a module folder can exist without being part of the application manifest.
modules/billing/If billing is not declared in vix.app, it is not part of the active module graph. The check command may warn about this because the state can be intentional during migration, but it can also mean a module was copied or created without being registered.
Declare the module when it should belong to the application.
[module.billing]
enabled = true
path = "modules/billing"
kind = "backend"
depends = [
"auth",
]2
3
4
5
6
7
If the module should stay in the repository but not be active yet, declare it as disabled.
[module.billing]
enabled = false
path = "modules/billing"
kind = "backend"
depends = [
"auth",
]2
3
4
5
6
7
This keeps the project state explicit.
Module declared but folder is missing
If vix.app declares a module but the folder does not exist, the manifest and filesystem are out of sync.
[module.auth]
enabled = true
path = "modules/auth"
kind = "backend"
depends = []2
3
4
5
The path must exist relative to the project root.
modules/auth/Fix the issue by restoring the missing folder, correcting the path, or creating the module skeleton.
vix modules add authIf the module was moved to another directory, update the path instead.
[module.auth]
enabled = true
path = "features/auth"
kind = "backend"
depends = []2
3
4
5
Then run the check again.
vix modules checkEnabled module is missing CMakeLists.txt
An enabled module must have a module build file.
modules/auth/CMakeLists.txtThis file creates the module target and alias target. Without it, the generated build cannot load the module correctly.
Restore the missing file from the module skeleton or recreate the module structure. For a backend module, the target should compile the module sources, expose the public include directory, keep the private source directory private, and link the Vix runtime target when needed.
After restoring the file, run:
vix modules check
vix build2
Enabled module is missing vix.module
An enabled module should also have a vix.module file.
modules/auth/vix.moduleFor a backend module, the file usually looks like this:
name = "auth"
kind = "backend"
[routes]
prefix = "/api/auth"
[tests]
enabled = true2
3
4
5
6
7
8
For a simple module, it usually looks like this:
name = "auth"
kind = "module"
[exports]
include = "include"
[tests]
enabled = true2
3
4
5
6
7
8
The module manifest describes the module itself. It is not the same as the root vix.app declaration.
vix modules list says vix.app not found
vix modules list, enable, and disable operate on module declarations in vix.app. If the project does not have a root vix.app, those commands cannot list or change manifest-based module state.
For a CMake-first project, active module usage is usually controlled by CMake. The important workflow is:
vix modules init
vix modules add auth
vix modules check2
3
Then link the module from CMake.
target_link_libraries(my_server PRIVATE api::auth)Use vix modules list, enable, and disable mainly in projects where vix.app is the source of truth for the active module graph.
Module is not being registered
If a backend module exists but its routes are not available at runtime, check whether the module is enabled in vix.app.
[module.auth]
enabled = true
path = "modules/auth"
kind = "backend"
depends = []2
3
4
5
A disabled module remains on disk, but it is not wired into the generated application registration bridge.
[module.auth]
enabled = false
path = "modules/auth"
kind = "backend"
depends = []2
3
4
5
Enable the module.
vix modules enable authThen run:
vix modules check
vix build2
Also confirm that the application template calls the generated registration entry point.
vix::app_generated::register_app_modules(app);In generated backend projects, this call belongs in AppBootstrap. In generated application projects, it is usually called through app::ModuleRegistry.
Routes compile but do not appear
If the project builds but the module route does not respond, confirm that the module entry point registers the controller.
void AuthModule::register_routes(vix::App &app)
{
controllers::AuthController::register_routes(app);
}2
3
4
Then confirm that the controller registers the expected route.
void AuthController::register_routes(vix::App &app)
{
app.get("/api/auth", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.json({
"ok", true,
"module", "auth"
});
});
}2
3
4
5
6
7
8
9
10
11
12
The route prefix in vix.module is useful for checks and ownership, but the actual route still has to be registered by the module code.
[routes]
prefix = "/api/auth"2
Duplicate route prefix
Backend modules should not claim the same route prefix.
[routes]
prefix = "/api/auth"2
If two modules use the same prefix, the module check command reports a conflict. This often happens after copying a module folder and changing the module name without updating vix.module.
Give each routed module its own prefix.
auth -> /api/auth
projects -> /api/projects
builds -> /api/builds
packages -> /api/packages2
3
4
Then run:
vix modules checkEnabled module depends on a disabled module
An enabled module cannot depend on a module that is disabled.
[module.auth]
enabled = false
path = "modules/auth"
kind = "backend"
depends = []
[module.projects]
enabled = true
path = "modules/projects"
kind = "backend"
depends = [
"auth",
]2
3
4
5
6
7
8
9
10
11
12
13
This state is invalid because projects is active but the dependency it needs is inactive.
Fix it by enabling the dependency:
vix modules enable author by disabling the dependent module:
vix modules disable projectsThen check the graph again.
vix modules checkModule depends on an undeclared module
A module dependency should point to another module declared in vix.app.
[module.projects]
enabled = true
path = "modules/projects"
kind = "backend"
depends = [
"auth",
]2
3
4
5
6
7
If auth is not declared, the module graph is incomplete.
Declare the missing module.
[module.auth]
enabled = true
path = "modules/auth"
kind = "backend"
depends = []2
3
4
5
Then run:
vix modules checkCircular module dependency detected
A cycle means modules depend on each other in a loop.
auth -> projects -> authThis usually means the boundary between the modules is not clear enough. One module may be reaching into another module because a shared concept has no proper home.
Break the cycle by making one direction clear.
projects -> author by moving shared behavior into a lower-level module.
identity
auth -> identity
projects -> identity2
3
After changing the graph, update vix.app and the module CMake target links, then run:
vix modules check
vix build2
Public header includes a private file
Public headers should not include files from another module’s src/ directory.
#include "../../auth/src/AuthStore.hpp"That include makes private implementation part of another module’s public surface. It may compile, but it weakens the boundary between modules.
Move the needed type or function into a public header.
modules/auth/include/auth/AuthStore.hppThen include it through the module public path.
#include <auth/AuthStore.hpp>If another module uses that header, declare the dependency.
target_link_libraries(api_projects
PUBLIC
api::auth
)2
3
4
Then run:
vix modules checkCross-module include without explicit dependency
If a public header from projects includes a public header from auth, the dependency should also be visible in the module build file.
#include <auth/api.hpp>The projects module should link to auth.
target_link_libraries(api_projects
PUBLIC
api::auth
)2
3
4
Without the target dependency, the include may work only because include paths leaked from somewhere else. That makes the build fragile.
Declare the dependency, then run:
vix modules check
vix build2
Generated files were edited manually
Files under .vix/generated/app/ are generated by Vix.
.vix/generated/app/Do not edit generated registration or generated CMake files to add modules. Those changes can disappear on the next build.
Change the source files instead:
vix.app
modules/auth/
modules/auth/vix.module
modules/auth/CMakeLists.txt2
3
4
Then rebuild.
vix modules check
vix build2
The generated files should be treated as output, not as the project source of truth.
vix.app is ignored because CMakeLists.txt exists
Vix resolves existing CMake projects first. If the project root contains both files, the root CMakeLists.txt wins.
api/
CMakeLists.txt
vix.app2
3
Resolution order:
1. CMakeLists.txt
2. vix.app2
This protects existing CMake projects from changing behavior just because a manifest was added during migration.
If the project is meant to use vix.app as the active application manifest, remove or move the root CMakeLists.txt when the migration is ready.
api/
vix.app
src/
include/
modules/2
3
4
5
Then build again.
vix modules check
vix build2
Wrong project name in CMake targets
Vix uses the project name to generate module targets.
api_auth
api::auth2
In CMake projects, the name is detected from the root project(...) call. If that name is not the prefix you want, pass the project name explicitly.
vix modules add auth --project apiFor checks, use:
vix modules check --project apiThis is useful when the directory name, CMake project name, and main target name do not match.
Module name was normalized
Module names may contain hyphens, but Vix normalizes hyphens to underscores for generated identifiers.
user-profile -> user_profileThat affects generated folders, targets, namespaces, and class names.
modules/user_profile/
api_user_profile
api::user_profile
UserProfileModule2
3
4
Use the normalized name when checking generated files or linking module targets.
CMake project was not patched
If a CMake-first project does not load modules, check whether cmake/vix_modules.cmake is included from the root build.
include(${CMAKE_CURRENT_LIST_DIR}/cmake/vix_modules.cmake)If you used --no-patch, Vix created the loader but did not edit the root CMakeLists.txt.
vix modules init --no-patchAdd the include manually where it fits your project.
For custom CMake projects, this is often the better approach because the project keeps control of its build order.
Auto-link used the wrong target
In a simple CMake project, vix modules add <name> can insert an auto-link block for the detected project target. This works best when the root CMake project name and the main target name are the same.
If the actual main target has another name, use manual linking.
vix modules add auth --no-linkThen link the module to the correct target.
target_link_libraries(my_server PRIVATE api::auth)This keeps module generation useful without forcing the project to follow a specific root target name.
Recommended diagnosis order
When a module problem is unclear, use this order.
1. Run vix modules check.
2. Confirm the module folder exists.
3. Confirm the module is declared in vix.app when using vix.app mode.
4. Confirm enabled = true when the module should be active.
5. Confirm CMakeLists.txt and vix.module exist inside the module.
6. Confirm route prefixes are unique for routed modules.
7. Confirm public headers do not include private src/ paths.
8. Confirm cross-module includes have explicit dependencies.
9. Build again.2
3
4
5
6
7
8
9
The commands are usually:
vix modules list
vix modules check
vix build2
3
For a full local validation:
vix modules check
vix check --tests --run2
Next step
Return to best practices when the module structure works but the module graph is becoming hard to read.
