Troubleshooting
Common problems encountered during development and migration, with solutions.
Leftover @/ imports in packages
Problem: Files in packages/ use @/ path alias, which only works inside apps/:
Module not found: Can't resolve '@/config/platforms'Solution: Replace with @numa/* workspace imports:
// Before (broken in packages)
import { PLATFORMS } from "@/config/platforms";
// After (correct)
import { PLATFORMS } from "@numa/config/platforms";Find offenders:
rg "from ['\"]@/" packages/Circular dependency between packages
Problem: Package A depends on B, and B depends on A:
WARN There are cyclic workspace dependenciesSolution: Use dependency inversion — accept the dependency as a prop:
// Instead of importing directly:
export function MyProvider({ children, fallback }: Props) {
return isLoading ? fallback : children;
}Detect cycles: pnpm install prints warnings about cyclic workspace dependencies.
Missing TypeScript type declarations
Problem:
Cannot find module 'react' or its corresponding type declarations.Solution: Add @types/react and @types/node to devDependencies in every package that uses them:
cd packages/my-package
pnpm add -D @types/react @types/nodeWrong import paths (.service suffix)
Problem:
Module not found: Can't resolve '@numa/api/services/auth.service'Solution: Remove the .service suffix:
// Before (broken)
import { useLoginMutation } from "@numa/api/services/auth.service";
// After (correct)
import { useLoginMutation } from "@numa/api/services/auth";Wrong i18n import
Problem:
Module not found: Can't resolve 'use-intl'Solution: Import from next-intl, not use-intl:
// Before (broken)
import { useTranslations } from "use-intl";
// After (correct)
import { useTranslations } from "next-intl";Missing direct dependency
Problem:
Cannot find module 'axios' or its corresponding type declarations.Solution: Add the package as a direct dependency, even for type-only imports:
cd apps/my-app
pnpm add axiospnpm’s strict node_modules structure isolates packages by default — don’t rely on transitive dependencies.
Missing sub-path export
Problem:
Module not found: Can't resolve '@numa/ui/shared/layout/auth/auth-form-footer'Solution: Add the sub-path to packages/ui/package.json exports:
{
"exports": {
"./shared/layout/auth/auth-form-footer": "./shared/layout/auth/auth-form-footer.tsx"
}
}App-specific components in shared packages
Problem: A component in @numa/ui imports from @/components/... — a path that only exists in one app.
Solution: Move app-specific components to the app that owns them. Keep shared types/interfaces in the package:
cp packages/ui/shared/ui/form/g-form.tsx apps/auth/components/g-form.tsxRule: If a component imports from @/, it cannot live in a shared package.
Google Fonts fetch failure
Problem:
next/font: error: Failed to fetch 'Space Grotesk' from Google Fonts.Solutions:
- Ensure network access during build (Google Fonts are fetched at build time)
- Use
next/font/localwith downloaded font files instead - In Docker, ensure the build stage has network access
cva type inference issues
Problem:
Type 'string' is not assignable to type '"default" | "sm" | "lg"'.Solution: Cast props to the expected literal types:
const classes = buttonVariants({
variant: variant as VariantProps<typeof buttonVariants>["variant"],
size: (size ?? "default") as ButtonSize,
});Quick reference commands
# Find leftover @/ imports in packages
rg "from ['\"]@/" packages/
# Find imports with .service suffix
rg "\.service['\"]" apps/ packages/
# Find wrong i18n imports
rg "from ['\"]use-intl" apps/ packages/
# Check for cycles
pnpm install
# Clean everything and reinstall
pnpm clean:all && pnpm install
# Type check everything
pnpm type:check
# Build a specific package to find missing deps
pnpm --filter @numa/ui build