Safe DSL: a definition depending on an unbound interface compiles fine and crashes at runtime

Open
#85 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
kotlin

Research direction

Reproduce the issue with the linked sample using :app:compileDebugKotlin or assembleDebug, with compileSafety, strictSafety, and debugLogs enabled. Start from the Safe DSL verification path and the warnings about missing hint functions and an unresolvable modules() argument. Done means the unbound MissingDependency makes compilation fail instead of allowing a runtime crash, and skipped verification is no longer silent.

Written by the indexing model from the issue text.

Description

status:waiting_feedback 👋

With the Koin compiler plugin and the Safe DSL, I can declare a definition whose constructor takes
an interface that has no implementation and no definition anywhere in the project. The build
succeeds and the app crashes at runtime. Compile-safety does not catch it.

Reproducer: https://github.com/DogukanBas/koin-compiler-plugin-multimodule-dsl-sample

Versions

Koin 4.2.1 · koin-annotations 2.3.1 · koin-compiler-plugin 1.1.0 · Kotlin 2.3.21 · AGP 9.0.1

Code

MissingDependency is never bound:

interface MissingDependency {
    fun foo()
}

class HomeViewModel internal constructor(
    repository: SampleRepository,
    missing: MissingDependency,
) : ViewModel() {
    init { missing.foo() }
}

Declared through the Safe DSL:

object FeatureUiModule {
    val viewModels = module {
        viewModel<HomeViewModel>()
    }
}

Loaded at the entry point:

@KoinApplication(modules = [AppModule::class])
class MainApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin<MainApplication> {
            modules(FeatureUiModule.viewModels)
        }
    }
}

Compile-safety is explicitly enabled in app/build.gradle.kts:

koinCompiler {
    compileSafety = true
    strictSafety = true
}

Expected

:app:compileDebugKotlin fails: MissingDependency has no definition.

Actual

./gradlew :app:assembleDebug
BUILD SUCCESSFUL

The app crashes when HomeViewModel is resolved.

Note

Verification is not failing — it is being skipped, silently. With debugLogs = true:

-> WARNING: ...FeatureModule has @ComponentScan but no scan hints found (hint functions unavailable)
-> SKIPPED: some dependency modules have incomplete definitions (hint functions unavailable)
   modules() at startKoin has an UNRESOLVABLE argument — loaded set unknown

Nothing is printed at the default log level, so the project looks verified when nothing is verified.

Dominant language
Kotlin
Stars
82
Forks
15
Avg merge
1m
Merged PRs (30d)
1

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from InsertKoinIO/koin-compiler-plugin

All issues in InsertKoinIO/koin-compiler-plugin

Similar issues

More Kotlin issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.