oven-sh/bun · error · Error
Call is not known at bundle-time: '$$${name}${inner.result}'
Error message
Call is not known at bundle-time: '$$${name}${inner.result}' What it means
The builtin-module preprocessor evaluates $rust/$cpp/$newRustFunction/$newCppFunction calls at bundle time: it slices out the argument text, converts single quotes to double quotes, and JSON.parses it. These macros register native FFI functions and must take literal arguments; if the slice is not parseable JSON (template literals, variables, escapes that break quoting), the call is not statically known and codegen throws.
Source
Thrown at src/codegen/replacements.ts:249
true,
];
} else if (["rust", "cpp", "newRustFunction", "newCppFunction"].includes(name)) {
const kind = name.includes("ust") ? "rust" : "cpp";
const is_create_fn = name.startsWith("new");
const inner = sliceSourceCode(rest, true);
let args;
try {
const str =
"[" +
inner.result
.slice(1, -1)
.replaceAll("'", '"')
.replace(/,[\s\n]*$/s, "") +
"]";
args = JSON.parse(str);
} catch {
throw new Error(`Call is not known at bundle-time: '$${name}${inner.result}'`);
}
if (
args.length != (is_create_fn ? 3 : 2) ||
typeof args[0] !== "string" ||
typeof args[1] !== "string" ||
(is_create_fn && typeof args[2] !== "number")
) {
if (is_create_fn) {
throw new Error(`$${name} takes three arguments, but got '$${name}${inner.result}'`);
} else {
throw new Error(`$${name} takes two string arguments, but got '$${name}${inner.result}'`);
}
}
const id = registerNativeCall(kind, args[0], args[1], is_create_fn ? args[2] : null);
return [slice.slice(0, match.index) + "__intrinsic__lazy(" + id + ")", inner.rest, true];
} else if (name === "isPromiseFulfilled" || name === "isPromiseRejected" || name === "isPromisePending") {View on GitHub (pinned to 8c5296ac45)
Solutions
- Inline the arguments as literals: $rust("StructName", "functionName").
- Use single-quoted or plain double-quoted strings without internal double quotes; escape any nested quotes as \".
- Do not wrap macro arguments in template literals or pass variables — the bundler cannot evaluate them.
Example fix
// before
const s = "BunObject";
const fn = $rust(s, "open");
// after
const fn = $rust("BunObject", "open"); Defensive patterns
Strategy: validation
Validate before calling
const macroCallRe = /\$\w+\s*\(/g;
const literalArgsRe = /^\$\w+\(\s*(['"][^'"]*['"]\s*(,\s*['"][^'"]*['"]\s*)*)?\)$/;
for (const line of builtinSource.split("\n")) {
if (macroCallRe.test(line) && !literalArgsRe.test(line.trim())) {
console.warn(`check macro call uses only literal args: ${line.trim()}`);
}
} Prevention
- Treat $rust/$cpp/$new*/$bindgenFn arguments as data, not code: literals only, never variables or template literals.
- Avoid double quotes inside argument strings; the preprocessor swaps single quotes to double and JSON.parses.
- Centralize bindings in one file so a review of that file covers all macro call sites.
When it happens
Trigger: Calling $rust(...) / $cpp(...) / $newRustFunction(...) inside src/js with anything except plain string/number literals — e.g. `const n = "Bun"; $rust(n, "open")`, backtick strings, or strings containing unescaped double quotes.
Common situations: Refactoring builtin code to hoist the struct/function names into constants; adding a new $rust binding and pasting a template-literal call site.
Related errors
- $$${name} takes three arguments, but got '$$${name}${inner.r
- $$${name} takes two string arguments, but got '$$${name}${in
- Unknown preprocessor macro ${name}
- slice/str param `${ty}` is not FFI-safe; pass (ptr, len)
- ${where}: cannot parse param `${raw}`
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/f9e987bb60083c1e.
Report an issue: GitHub.