Summary
--knowledge-base is the one CLI path argument that never gets home expansion. prepareKnowledgeBase() calls resolve() on the raw value, so on a shell that passes ~ literally the path is resolved against the current working directory and the scan fails before it starts.
This is adjacent to #57 but outside it: #57 enumerates the path arguments outside scan, and --knowledge-base belongs to scan.
Environment
@openai/codex-security 0.1.5, current main at ea19f24
- macOS 15 (Darwin 25.5.0), Node.js 24.11.1, Bun 1.3.14
Where it is
sdk/typescript/src/knowledge-base.ts:
const path = resolve(requested);
Calling prepareKnowledgeBase(["~/docs"]) directly from the package root:
ERR: ENOENT: no such file or directory, lstat '<repo>/sdk/typescript/~/docs'
The two producers that reach it are scan's options.knowledgeBase and the values read back out of a stored scan recipe. The recipe path already holds absolute values, so only the CLI-supplied form is affected.
Reproduction
codex-security scan . --knowledge-base '~/docs'
Quoting is what makes this reachable — an unquoted ~/docs is expanded by the shell. It shows up for real when the value comes from a config file, a CI variable, a Makefile, or any context that does not go through shell word expansion.
Expected behavior
~ and ~/… in --knowledge-base resolve against the user's home directory, the same way the other CLI path arguments do.
Correction to an earlier version of this issue
I originally wrote that bulk-scan has no --knowledge-base option. That is wrong on current main: it does, declared at sdk/typescript/src/cli.ts:1281 and reaching the same prepareKnowledgeBase() via cli.ts:1405. So both scan and bulk-scan are affected, which strengthens the case for expanding inside prepareKnowledgeBase rather than at either CLI boundary — one site covers both.
The sibling bulk-scan path options are already covered: --plugin-path and --python both expand in runtime.ts.
Summary
--knowledge-baseis the one CLI path argument that never gets home expansion.prepareKnowledgeBase()callsresolve()on the raw value, so on a shell that passes~literally the path is resolved against the current working directory and the scan fails before it starts.This is adjacent to #57 but outside it: #57 enumerates the path arguments outside
scan, and--knowledge-basebelongs toscan.Environment
@openai/codex-security0.1.5, currentmainatea19f24Where it is
sdk/typescript/src/knowledge-base.ts:Calling
prepareKnowledgeBase(["~/docs"])directly from the package root:The two producers that reach it are
scan'soptions.knowledgeBaseand the values read back out of a stored scan recipe. The recipe path already holds absolute values, so only the CLI-supplied form is affected.Reproduction
Quoting is what makes this reachable — an unquoted
~/docsis expanded by the shell. It shows up for real when the value comes from a config file, a CI variable, a Makefile, or any context that does not go through shell word expansion.Expected behavior
~and~/…in--knowledge-baseresolve against the user's home directory, the same way the other CLI path arguments do.Correction to an earlier version of this issue
I originally wrote that
bulk-scanhas no--knowledge-baseoption. That is wrong on currentmain: it does, declared atsdk/typescript/src/cli.ts:1281and reaching the sameprepareKnowledgeBase()viacli.ts:1405. So bothscanandbulk-scanare affected, which strengthens the case for expanding insideprepareKnowledgeBaserather than at either CLI boundary — one site covers both.The sibling
bulk-scanpath options are already covered:--plugin-pathand--pythonboth expand inruntime.ts.