svelte: Error: offset is longer than source length w/ Svelte v3.38.3

Since the update to the latest Svelte version (3.38.3) an error is thrown from Vite when a request comes in.

Logs

$ svelte-kit dev --port 8000

  SvelteKit v1.0.0-next.116

  local:   http://localhost:8000
  network: not exposed

  Use --host to expose server to other devices on this network


offset is longer than source length!
Error: offset is longer than source length!
    at numberToPos (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:4234:15)
    at formatError (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44611:24)
    at TransformContext.error (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44591:19)
    at Object.transform (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44799:25)
    at async transformRequest (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:60267:29)
    at async instantiateModule (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:69930:10)

I traced it to an error in one of my style blocks not displaying because the offset/source length is incorrect:

ERR:: CompileError [ValidationError]: :global(...) must contain a single selector
    at error (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:16752:19)
    at Component.error (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:29036:9)
    at Selector$1.validate (file:///<path/to/the/project>t/node_modules/svelte/compiler.mjs:27872:35)
    at file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:28369:22
    at Array.forEach (<anonymous>)
    at Rule$1.validate (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:28368:24)
    at file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:28650:19
    at Array.forEach (<anonymous>)
    at Stylesheet.validate (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:28649:23)
    at new Component (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:28828:25) {
  code: 'css-invalid-global-selector',
  start: { line: 89, column: 10, character: 2845 },
  end: { line: 89, column: 58, character: 2893 },
  pos: 2845,
  ...
  frame: '87:   }\n' +
    '88: \n' +
    '89:   .slider :global(.noUi-handle:after, .noUi-handle:before) {\n' +
    '              ^\n' +
    '90:     left: 10px !important;\n' +
    '91:     top: 4px !important;',
  ...

The offset is 2845 (offset/pos) but the source length is 2417 in that case. https://github.com/vitejs/vite/blob/460d1cda317e4c4d03434f2b3d8de9152620005b/packages/vite/src/node/utils.ts#L252

export function numberToPos(
  source: string,
  offset: number | { line: number; column: number }
): { line: number; column: number } {
  if (typeof offset !== 'number') return offset
  if (offset > source.length) {
    throw new Error('offset is longer than source length!')
  }
  const lines = source.split(splitRE)

Information about your SvelteKit Installation:

System:
    OS: macOS 10.15.4
    CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
    Memory: 367.08 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 16.0.0 - ~/.nvm/versions/node/v16.0.0/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.10.0 - ~/.nvm/versions/node/v16.0.0/bin/npm
  Browsers:
    Brave Browser: 76.0.68.132
    Chrome: 91.0.4472.114
    Chrome Canary: 93.0.4551.0
    Edge: 91.0.864.54
    Firefox: 72.0.2
    Firefox Developer Edition: 89.0
    Safari: 13.1
  npmPackages:
    @sveltejs/adapter-node: ^1.0.0-next.27 => 1.0.0-next.27 
    @sveltejs/adapter-static: ^1.0.0-next.13 => 1.0.0-next.13 
    @sveltejs/kit: ^1.0.0-next.116 => 1.0.0-next.116 
    svelte: 3.38.3 => 3.38.3 

Let me know if this info is sufficient and reproducible with any SvelteKit app with the latest Svelte version + multiple selectors in a single :global like :global(.foo, .bar) or a repro is needed.

PS: Not sure if the bug report is correct here or should be created in the svelte or vite-plugin-svelte repo.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 3
  • Comments: 19 (13 by maintainers)

Most upvoted comments

I did that but it does not prevent the error. I added the error.pos (offset) from Svelte (2845) and the source length from Vite (2515) to Vite’s error message:

offset is longer than source length! 2845 2515
Error: offset is longer than source length! 2845 2515
    at numberToPos (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:4234:15)
    at formatError (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44612:24)
    at TransformContext.error (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44591:19)
    at Object.transform (/<path/to/the/project>/node_modules/vite/dist/node/chunks/dep-0ed4fbc0.js:44802:25)

The offset is set from the transpiled file from Svelte and added to the error object (error.pos) which could be okay but Vite uses the non-transpiled file and checks if the length of it is greater than the offset (error.pos), which might be the case if the error occurs further up but then the offset is still not correct.

I moved the wrong :global up as a test, so the offset (error.pos) is definitely lower than the source length and then I see the correct error:

:global(...) must contain a single selector
ValidationError: :global(...) must contain a single selector
    at error (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:16752:19)
    at Component.error (file:///<path/to/the/project>/node_modules/svelte/compiler.mjs:29038:9)

tl;dr: If an error occurred at the end of the Svelte file, the offset is higher than the source length (not transpiled) because the error position from Svelte is taken from the transpiled file. If an error occurs at a position where the offset is still within the range of the source length, then everything is fine, but if you were to compare the error position (offset) from Svelte and the error position from the Vite’s file source, it would not match.

EDIT: Either Vite should use the transpiled Svelte file as source (not sure where this is coming from) or the error.pos from Svelte should be set from the non-transpiled file.