{"id":"3254c4bfe863192d","repo":"vitejs/vite","slug":"the-value-passed-to-base-option-was-malformed-i","errorCode":null,"errorMessage":"The value passed to \"base\" option was malformed. It should be a valid URL.","messagePattern":"The value passed to \"base\" option was malformed\\. It should be a valid URL\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/config.ts","lineNumber":2340,"sourceCode":"  }\n\n  // parse base when command is serve or base is not External URL\n  if (!isBuild || !isExternal) {\n    base = new URL(base, 'http://vite.dev').pathname\n    // ensure leading slash\n    if (base[0] !== '/') {\n      base = '/' + base\n    }\n  }\n\n  return base\n}\n\nfunction decodeBase(base: string): string {\n  try {\n    return decodeURI(base)\n  } catch {\n    throw new Error(\n      'The value passed to \"base\" option was malformed. It should be a valid URL.',\n    )\n  }\n}\n\nexport function sortUserPlugins(\n  plugins: (Plugin | Plugin[])[] | undefined,\n): [Plugin[], Plugin[], Plugin[]] {\n  const prePlugins: Plugin[] = []\n  const postPlugins: Plugin[] = []\n  const normalPlugins: Plugin[] = []\n\n  if (plugins) {\n    plugins.flat().forEach((p) => {\n      if (p.enforce === 'pre') prePlugins.push(p)\n      else if (p.enforce === 'post') postPlugins.push(p)\n      else normalPlugins.push(p)\n    })","sourceCodeStart":2322,"sourceCodeEnd":2358,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/config.ts#L2322-L2358","documentation":"In decodeBase (config.ts:2336-2343), Vite runs decodeURI on the resolved base value; if the value contains malformed percent-encoding (e.g. a stray '%' not forming a valid escape), decodeURI throws URIError which Vite re-wraps as 'The value passed to base option was malformed'. The base must be a valid, decodable URL/path.","triggerScenarios":"Setting config base to a string containing an invalid percent sequence such as '/my%path/' or '/vite%/'.","commonSituations":"Passing a deployment prefix with a literal '%' (e.g. a versioned path), an unencoded query/fragment, or a copy-pasted URL with reserved characters.","solutions":["Correct the base to a valid path/URL, e.g. '/my-app/'.","Percent-encode any literal special characters properly (e.g. '%25' for a literal '%') or remove them.","Use an absolute URL or a simple leading-slash path as the docs recommend."],"exampleFix":"// before\nexport default { base: '/vite%/' }\n// after\nexport default { base: '/vite/' }","handlingStrategy":"validation","validationCode":"function assertValidBase(base: string) {\n  try { decodeURI(base) } catch { throw new Error(`Malformed base: ${base}`) }\n}","typeGuard":"function isDecodableBase(base: string): boolean {\n  try { decodeURI(base); return true } catch { return false }\n}","tryCatchPattern":null,"preventionTips":["Keep base a simple leading-slash path or absolute URL.","Percent-encode literal special characters correctly (e.g. %25 for %).","Validate base in CI config checks."],"tags":["config","base","url","validation"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}