{"record":{"id":"b28b00abbc1ef21d","repo":"emberjs/ember.js","slug":"you-must-pass-either-the-hasvalue-or-the-hassch","errorCode":null,"errorMessage":"You must pass either the `hasValue` OR the `hasScheduledEffect` capability when defining a helper manager. Passing neither, or both, is not permitted.","messagePattern":"You must pass either the `hasValue` OR the `hasScheduledEffect` capability when defining a helper manager\\. Passing neither, or both, is not permitted\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@glimmer/manager/lib/public/helper.ts","lineNumber":41,"sourceCode":"import { argsProxyFor } from '../util/args-proxy';\nimport { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities';\n\nexport function helperCapabilities<Version extends keyof HelperCapabilitiesVersions>(\n  managerAPI: Version,\n  options: Partial<HelperCapabilities> = {}\n): HelperCapabilities {\n  debugAssert(\n    managerAPI === '3.23',\n    () =>\n      `Invalid helper manager compatibility specified; you specified ${managerAPI}, but only '3.23' is supported.`\n  );\n\n  if (\n    DEBUG &&\n    (!(options.hasValue || options.hasScheduledEffect) ||\n      (options.hasValue && options.hasScheduledEffect))\n  ) {\n    throw new Error(\n      'You must pass either the `hasValue` OR the `hasScheduledEffect` capability when defining a helper manager. Passing neither, or both, is not permitted.'\n    );\n  }\n\n  if (DEBUG && options.hasScheduledEffect) {\n    throw new Error(\n      'The `hasScheduledEffect` capability has not yet been implemented for helper managers. Please pass `hasValue` instead'\n    );\n  }\n\n  return buildCapabilities({\n    hasValue: Boolean(options.hasValue),\n    hasDestroyable: Boolean(options.hasDestroyable),\n    hasScheduledEffect: Boolean(options.hasScheduledEffect),\n  });\n}\n\n////////////","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/manager/lib/public/helper.ts#L23-L59","documentation":"Helper manager capabilities require exactly one of `hasValue` or `hasScheduledEffect` to be set. Passing neither (capabilities say nothing about the helper's semantics) or both (contradictory semantics) is invalid, and `helperCapabilities()` throws in DEBUG. This forces every helper manager to declare whether it returns a value eagerly or produces a scheduled effect.","triggerScenarios":"`helperCapabilities('3.23')` with no options; with `{ hasValue: true, hasScheduledEffect: true }`; or with options typed/spelled incorrectly so both flags end up truthy or neither does (e.g. passing unrelated option keys).","commonSituations":"First-time helper manager authors omitting capability options; combining flags 'to be safe' from example code; refactors that renamed flags leaving both stale keys.","solutions":["Pass exactly one flag: `helperCapabilities('3.23', { hasValue: true })` for value helpers","Use `{ hasScheduledEffect: true }` only for effect-style helpers — but see error 59, currently unimplemented, so use hasValue","Remove the other flag if both were passed","Verify the option key spelling matches hasValue/hasScheduledEffect"],"exampleFix":"// before\ncapabilities = helperCapabilities('3.23', { hasValue: true, hasScheduledEffect: true });\n// after\ncapabilities = helperCapabilities('3.23', { hasValue: true });","handlingStrategy":"validation","validationCode":"import { capabilities } from '@glimmer/manager';\nfunction buildHelperCaps(opts: { hasValue?: boolean; hasScheduledEffect?: boolean }) {\n  const count = Number(!!opts.hasValue) + Number(!!opts.hasScheduledEffect);\n  if (count !== 1) throw new Error('pass exactly one of hasValue or hasScheduledEffect');\n  return capabilities('3.23', opts);\n}","typeGuard":"function hasExactlyOneCapability(o: { hasValue?: boolean; hasScheduledEffect?: boolean }): boolean { return Number(!!o.hasValue) + Number(!!o.hasScheduledEffect) === 1; }","tryCatchPattern":"try { caps = helperCapabilities('3.23', opts); } catch (e) { if (/hasValue` OR the `hasScheduledEffect/.test(e.message)) caps = helperCapabilities('3.23', { hasValue: true }); else throw e; }","preventionTips":["Always pass exactly one capability flag to helperCapabilities","Prefer hasValue since hasScheduledEffect is unimplemented","Centralize capability construction in one helper function"],"tags":["helper-manager","capabilities","configuration"],"backgroundTag":"invalid-helper-capability-flags","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}