Skip to content
Latchkey

Webpack css-loader "Can't resolve '<asset>'" in url() - Fix in CI

By default css-loader resolves url() references in stylesheets as module requests, like JS imports. A url() pointing at a missing file, a wrong/miscased path, or a host-absolute URL that should not be resolved makes the build fail with "Can't resolve".

What this error means

The build fails with Module not found: Error: Can't resolve './images/bg.png' originating from a CSS file's url(). It is deterministic and names the stylesheet and the referenced asset.

webpack output
ERROR in ./src/styles/main.css (./node_modules/css-loader/dist/cjs.js!./src/styles/main.css)
Module not found: Error: Can't resolve './images/Bg.png' in '/app/src/styles'
 @ ./src/styles/main.css (url(./images/Bg.png))

Common causes

Asset path wrong or miscased

The url() points at a file that does not exist at that path, or its casing differs (Bg.png vs bg.png). Case-sensitive Linux CI fails where macOS resolved it.

A url() that should not be resolved

A root-relative (/assets/x.png served at runtime) or external URL is being treated as a module request, so Webpack tries and fails to resolve it at build time.

How to fix it

Fix the asset path and case

Point url() at the real file with exact casing, or move the asset so the relative path resolves.

CSS / Terminal
ls -la src/styles/images/   # confirm bg.png vs Bg.png
/* main.css */
.hero { background: url('./images/bg.png'); }

Skip resolution for runtime-served URLs

Tell css-loader not to resolve root-relative/external URLs it should leave untouched.

webpack.config.js
// webpack.config.js
{
  test: /\.css$/,
  use: [
    'style-loader',
    { loader: 'css-loader', options: { url: { filter: (u) => !u.startsWith('/') } } },
  ],
}

How to prevent it

  • Match url() asset paths and casing to real files.
  • Filter runtime-served URLs out of css-loader resolution.
  • Build CSS in CI so url() resolution gaps fail before deploy.

Frequently asked questions

What causes ""Can't resolve" in url()"?
The url() points at a file that does not exist at that path, or its casing differs (Bg.png vs bg.png). Case-sensitive Linux CI fails where macOS resolved it.
How do I fix "Can't resolve" in url()?
Point url() at the real file with exact casing, or move the asset so the relative path resolves.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card