{"id":"28512775163eb580","repo":"expressjs/express","slug":"unknown-value-for-etag-function-val","errorCode":null,"errorMessage":"unknown value for etag function: ' + val","messagePattern":"unknown value for etag function: ' \\+ val","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/utils.js","lineNumber":148,"sourceCode":"exports.compileETag = function(val) {\n  var fn;\n\n  if (typeof val === 'function') {\n    return val;\n  }\n\n  switch (val) {\n    case true:\n    case 'weak':\n      fn = exports.wetag;\n      break;\n    case false:\n      break;\n    case 'strong':\n      fn = exports.etag;\n      break;\n    default:\n      throw new TypeError('unknown value for etag function: ' + val);\n  }\n\n  return fn;\n}\n\n/**\n * Compile \"query parser\" value to function.\n *\n * @param  {String|Function} val\n * @return {Function}\n * @api private\n */\n\nexports.compileQueryParser = function compileQueryParser(val) {\n  var fn;\n\n  if (typeof val === 'function') {\n    return val;","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/expressjs/express/blob/a3714473feb3d2908add734d340e7755fd85e0a3/lib/utils.js#L130-L166","documentation":"compileETag (lib/utils.js:130-152) converts the app's 'etag' setting into a header-generation function. Only a function, true, false, 'weak', or 'strong' are valid; any other value reaches the switch default at line 148 and throws a TypeError. This fires when the setting is applied — i.e. at app.set('etag', val) time — not per request.","triggerScenarios":"app.set('etag', 'true') or any other string besides 'weak'/'strong' (string 'true'/'false' from env vars is the classic case); app.set('etag', 1); app.disable/enable are fine, but passing a misspelled mode like 'week' throws.","commonSituations":"Reading the value from process.env — environment variables are always strings, so ETAG=true becomes the invalid string 'true'; config files (YAML/JSON) delivering unexpected types; copying settings between Express apps with a serialization step that stringifies booleans.","solutions":["Use one of the supported values: app.set('etag', 'weak'), 'strong', true, false, or a custom function(body, encoding).","When sourcing from env vars, convert explicitly: app.set('etag', process.env.ETAG === 'true').","To disable ETags, prefer app.disable('etag')."],"exampleFix":"// before\napp.set('etag', process.env.ETAG); // 'true' (string) is invalid\n// after\napp.set('etag', process.env.ETAG === 'strong' ? 'strong' : 'weak');","handlingStrategy":"validation","validationCode":"const VALID_ETAG = new Set([true, false, 'strong', 'weak']);\nif (!VALID_ETAG.has(etagSetting) && typeof etagSetting !== 'function') {\n  throw new TypeError(`invalid 'etag' setting: ${JSON.stringify(etagSetting)}`);\n}\napp.set('etag', etagSetting);","typeGuard":"function isValidEtagSetting(val) {\n  return val === true || val === false || val === 'strong' || val === 'weak' || typeof val === 'function';\n}","tryCatchPattern":"try {\n  app.set('etag', config.etag);\n} catch (err) {\n  if (/unknown value for etag function/.test(err.message)) {\n    // config supplied an unsupported value — fail startup with a clear config error\n  }\n  throw err;\n}","preventionTips":["Only use documented values: true, false, 'strong', 'weak', or a custom function(body, encoding).","Validate config-file/env-derived values against the allowed set before calling app.set — env vars arrive as strings like 'true', which is invalid.","Set 'etag' once at startup so a bad value crashes on boot rather than mid-traffic."],"tags":["express","configuration","etag","settings"],"analyzedSha":"a3714473feb3d2908add734d340e7755fd85e0a3","analyzedAt":"2026-07-31T18:55:36.968Z","schemaVersion":2}