{"record":{"id":"a5df8ec264137b71","repo":"oxc-project/oxc","slug":"expected-a-literal-string-or-immutable-template-li","errorCode":null,"errorMessage":"Expected a literal string or immutable template literal","messagePattern":"Expected a literal string or immutable template literal","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/import/no_dynamic_require.rs","lineNumber":15,"sourceCode":"use oxc_ast::{AstKind, ast::Expression};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn no_dnyamic_require_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Expected a literal string or immutable template literal\")\n        .with_help(\"Replace the argument with a literal string or immutable template literal\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoDynamicRequire {\n    /// When `true`, also check `import()` expressions for dynamic module specifiers.\n    esmodule: bool,\n}\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Forbids imports that use an expression for the module argument. This includes\n    /// dynamically resolved paths in `require` or `import` statements.\n    ///\n    /// ### Why is this bad?","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/import/no_dynamic_require.rs#L1-L33","documentation":"Diagnostic from the oxlint rule import/no-dynamic-require (restriction category). It fires when the module argument of `require(...)` is not statically known — not a string literal and not a no-substitution template literal. Runtime-computed paths defeat static analysis: bundlers cannot trace them, code navigation breaks, and lint rules that need resolved modules (like no-cycle or no-named-as-default) silently lose visibility. With the `esmodule: true` option, `import(...)` expressions are checked the same way.","triggerScenarios":"`require(name)`, `require(\"../\" + name)`, `require(\\`../${name}\\`)`, `require(name())`; also `import(name)` / `import(\\`../${name}\\`)` when configured with `{ \"esmodule\": true }`. Only the first argument of require is checked, so `require(\"./foo\", \"bar\" + \"okay\")` passes. Emitted from no_dnyamic_require_diagnostic at crates/oxc_linter/src/rules/import/no_dynamic_require.rs:15 via is_static_value.","commonSituations":"Plugin loaders, i18n/locale loading, and config discovery code that builds paths at runtime; migrations that moved to bundlers (webpack/rollup/vite) where dynamic require breaks or warns; teams enabling esmodule checking after adopting dynamic import().","solutions":["Replace the computed path with a literal string, or a template literal without substitutions","Replace open-ended dynamic loading with an explicit static require map: `const modules = { a: () => require(\"./a\"), b: () => require(\"./b\") }` — keys stay analyzable","For genuinely dynamic loading (plugins, routes), scope the rule off for that file/directory and use bundler-native mechanisms (import.meta.glob, webpack context) deliberately","If import() with expressions is accepted in your codebase, do not enable `esmodule: true`"],"exampleFix":"// before\nrequire(`../locales/${locale}.json`);\n\n// after\nconst localeFiles = {\n  en: () => require(\"../locales/en.json\"),\n  de: () => require(\"../locales/de.json\"),\n};\nlocaleFiles[locale]();","handlingStrategy":"validation","validationCode":"// fail on computed require paths before review:\n// rg -n \"require\\\\s*\\\\(\\\\s*[^'\\\"`]\" src --type js\n// .oxlintrc.json: { \"rules\": { \"import/no-dynamic-require\": [\"warn\", { \"esmodule\": true }] } }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer a static require map with literal keys for finite module sets","Use bundler-native dynamic loading (import.meta.glob, webpack require.context) and scope this rule off those files","Only enable esmodule:true when your bundler truly cannot trace import(expr)"],"tags":["lint","oxlint","imports","dynamic-require","static-analysis","bundling"],"backgroundTag":"dynamic-module-path","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}