{"record":{"id":"d8d2acc9dc688277","repo":"zellij-org/zellij","slug":"only-relative-sibling-module-specifiers-are-suppor","errorCode":null,"errorMessage":"only relative sibling module specifiers are supported, found '{}' at {}","messagePattern":"only relative sibling module specifiers are supported, found '(.+?)' at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"xtask/src/assets.rs","lineNumber":240,"sourceCode":"        .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\",\n            name,\n            location\n        ));\n    }\n    Ok(())\n}\n\nfn top_level_declarations(chunk: &str) -> Vec<String> {\n    let mut names = Vec::new();","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/zellij-org/zellij/blob/98a0837077492d53dd252ab30bc3e43e41e504f4/xtask/src/assets.rs#L222-L258","documentation":"Module specifiers must be exactly `./name.js` — starting with `./` and ending with `.js` — so the flattener can map the import to a bundled sibling module. Bare names, parent paths, package specifiers, URLs, or extension-less paths are rejected.","triggerScenarios":"`import { x } from 'utils.js';` (missing ./), `from '../lib/x.js'`, `from 'lodash'`, `from './utils'` (missing .js).","commonSituations":"Editor auto-import inserting bare or extension-less specifiers; copying code from bundler-based projects (webpack/vite) where extensions are omitted; muscle memory from npm imports.","solutions":["Rewrite the specifier as './name.js' (keep the leading ./ and the .js suffix)","Vendor any npm dependency into a local sibling module file and import it relatively","Compare the exact specifier string quoted in the error against the ./x.js form"],"exampleFix":"// before (rejected)\nimport { debounce } from 'utils';\n\n// after\nimport { debounce } from './utils.js';","handlingStrategy":"validation","validationCode":"# specifiers must look like ./name.js\nfor spec in $(grep -hoE \"from ['\\\"][^'\\\"]+['\\\"]\" zellij-client/assets/*.js | sed -E \"s/from ['\\\"]([^'\\\"]+)['\\\"]/\\1/\"); do\n  case \"$spec\" in\n    ./*.js) ;;\n    *) echo \"unsupported specifier: $spec (expected ./name.js)\"; exit 1;;\n  esac\ndone","typeGuard":"fn is_relative_sibling_specifier(specifier: &str) -> bool {\n    specifier.strip_prefix(\"./\").is_some_and(|s| s.ends_with(\".js\"))\n}","tryCatchPattern":null,"preventionTips":["Always write imports as './name.js' with leading ./ and explicit .js extension","Vendor npm dependencies as local sibling module files instead of importing packages","Configure editor auto-import to use relative paths with extensions in this directory"],"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"}