{"record":{"id":"48854983c3d11d2c","repo":"zellij-org/zellij","slug":"missing-module-specifier-at","errorCode":null,"errorMessage":"missing module specifier at {}","messagePattern":"missing module specifier at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xtask/src/assets.rs","lineNumber":231,"sourceCode":"fn is_terminated_import(rest: &str) -> bool {\n    rest.ends_with(';') && rest.contains(\" from \")\n}\n\nfn is_import_binding_line(trimmed: &str) -> bool {\n    if trimmed.is_empty() || trimmed == \"{\" {\n        return true;\n    }\n    trimmed\n        .trim_end_matches(',')\n        .chars()\n        .all(|c| c.is_alphanumeric() || c == '_' || c == '$' || c == ' ')\n}\n\nfn validate_module_specifier(line: &str, location: &str) -> anyhow::Result<()> {\n    let specifier = line\n        .rsplit_once(\" from \")\n        .map(|(_, specifier)| specifier)\n        .ok_or_else(|| anyhow!(\"missing module specifier at {}\", location))?\n        .trim()\n        .trim_end_matches(';')\n        .trim_matches(|c| c == '\"' || c == '\\'');\n\n    let name = specifier\n        .strip_prefix(\"./\")\n        .and_then(|name| name.strip_suffix(\".js\"))\n        .ok_or_else(|| {\n            anyhow!(\n                \"only relative sibling module specifiers are supported, found '{}' at {}\",\n                specifier,\n                location\n            )\n        })?;\n\n    if !MODULE_ORDER.contains(&name) {\n        return Err(anyhow!(\n            \"module '{}' referenced at {} is not part of the bundle\",","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/xtask/src/assets.rs#L213-L249","documentation":"validate_module_specifier extracts the module path with `rsplit_once(\" from \")` from a line that reached specifier validation. If the line contains no ' from ' separator, no specifier can be located and bundling aborts.","triggerScenarios":"A side-effect import `import './utils.js';`; a re-export whose path was deleted (`export { a } from;`); an import line truncated so the from-clause is missing.","commonSituations":"Half-edited import/export lines after refactors or merge conflicts; scripts pasted without their from-clause.","solutions":["Give the statement a full specifier: `import { a } from './utils.js';`","Replace side-effect imports with a normal named import from that module (or drop them: the bundle is one file)","Fix the truncated line identified by the module.js:line location in the message"],"exampleFix":"// before (rejected: no ' from ')\nimport './utils.js';\n\n// after\nimport { bootstrap } from './utils.js';","handlingStrategy":"validation","validationCode":"# every import/export-from line must contain a ' from ' clause with a path\ngrep -nE '^(import|export)' zellij-client/assets/*.js | grep -v ' from ' && {\n  echo 'import/export statement missing from-clause'; exit 1;\n} || true","typeGuard":"fn has_module_specifier(line: &str) -> bool {\n    line.rsplit_once(\" from \").is_some()\n}","tryCatchPattern":null,"preventionTips":["No side-effect imports (`import './x.js';`): import a named binding instead","After truncating or merging import lines, grep for `from ` before bundling"],"tags":["javascript","bundler","import","specifier","assets"],"backgroundTag":null,"analyzedSha":"98a0837077492d53dd252ab30bc3e43e41e504f4","analyzedAt":"2026-08-16T13:02:01.396Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}