Summary
When stringImportPaths includes . (package root), dub expands $NAME sequences found in filenames under that tree. A file literally named $null (easy to create accidentally from PowerShell $null) makes the build fail with:
Error Invalid variable: null
No package metadata needs a $null variable — the filename alone is enough.
Repro
import subprocess, tempfile, json
from pathlib import Path
td = Path(tempfile.mkdtemp(prefix="dub-dollar-null-"))
(td / "source").mkdir()
(td / "dub.json").write_text(json.dumps({
"name": "dollar-null-repro",
"targetType": "executable",
"sourceFiles": ["source/app.d"],
"stringImportPaths": ["."]
}, indent=2), encoding="utf-8")
(td / "source" / "app.d").write_text(
'void main() { enum s = import("note.txt"); }\n', encoding="utf-8")
(td / "note.txt").write_text("ok\n", encoding="utf-8")
# Landmine: filename looks like a dub variable
(td / "$null").write_text("artifact\n", encoding="utf-8")
print(td)
raise SystemExit(subprocess.call(["dub", "build"], cwd=td))
Expected
Build succeeds (or only expands known tokens such as $PACKAGE_DIR in build settings, not arbitrary filenames discovered under stringImportPaths).
Actual
Error Invalid variable: null
Exit code 2 during “Generating using build”, before DMD runs.
Environment
- dub 1.41.0 (built Jan 6 2026)
- DMD 2.112.0
- Windows 10/11 + PowerShell
Workarounds
- Prefer named
stringImportPaths dirs (e.g. embed/, docs/) instead of .
- Delete stray
$null files (can appear from PowerShell/-of$null-style mistakes)
Why it matters
stringImportPaths "." is a common pattern in dub.sdl. On Windows, PowerShell’s $null makes this footgun realistic.
Summary
When
stringImportPathsincludes.(package root), dub expands$NAMEsequences found in filenames under that tree. A file literally named$null(easy to create accidentally from PowerShell$null) makes the build fail with:No package metadata needs a
$nullvariable — the filename alone is enough.Repro
Expected
Build succeeds (or only expands known tokens such as
$PACKAGE_DIRin build settings, not arbitrary filenames discovered understringImportPaths).Actual
Exit code 2 during “Generating using build”, before DMD runs.
Environment
Workarounds
stringImportPathsdirs (e.g.embed/,docs/) instead of.$nullfiles (can appear from PowerShell/-of$null-style mistakes)Why it matters
stringImportPaths "."is a common pattern indub.sdl. On Windows, PowerShell’s$nullmakes this footgun realistic.