emberjs/ember.js · error · Error

A resolved helper cannot be passed as a named argument as th

Error message

A resolved helper cannot be passed as a named argument as the syntax is ambiguously a pass-by-reference or invocation. Use the `{{helper 'foo-helper}}` helper to pass by reference or explicitly invoke the helper with parens: `{{(fooHelper)}}`.

What it means

In DEBUG, Glimmer's deprecate hook hard-throws for the 'argument-less-helper-paren-less-invocation' deprecation instead of warning. Passing a resolved helper as a named argument without parens is ambiguous (pass-by-reference vs invocation), so Ember errors to force explicit syntax.

Source

Thrown at packages/@ember/-internals/glimmer/lib/environment.ts:71

    );
  },

  assert(test: unknown, msg: string, options?: { id: string }) {
    if (DEBUG) {
      let id = options?.id;

      let override = VM_ASSERTION_OVERRIDES.filter((o) => o.id === id)[0];

      assert(override?.message ?? msg, test);
    }
  },

  deprecate(msg: string, test: unknown, options: { id: string }) {
    if (DEBUG) {
      let { id } = options;

      if (id === 'argument-less-helper-paren-less-invocation') {
        throw new Error(
          `A resolved helper cannot be passed as a named argument as the syntax is ` +
            `ambiguously a pass-by-reference or invocation. Use the ` +
            `\`{{helper 'foo-helper}}\` helper to pass by reference or explicitly ` +
            `invoke the helper with parens: \`{{(fooHelper)}}\`.`
        );
      }

      let override = VM_DEPRECATION_OVERRIDES.filter((o) => o.id === id)[0];

      if (!override) throw new Error(`deprecation override for ${id} not found`);

      // allow deprecations to be disabled in the VM_DEPRECATION_OVERRIDES array below
      if (!override.disabled) {
        deprecate(override.message ?? msg, Boolean(test), override);
      }
    }
  },
});

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Invoke the helper explicitly with parentheses: @bar={{(someHelper)}}
  2. Pass by reference deliberately with the helper keyword: @bar={{helper 'some-helper'}}
  3. If a plain value was intended, rename the colliding helper or fix the argument value

Example fix

// before
<MyInput @validator=requiredHelper />
// after
<MyInput @validator={{(requiredHelper)}} />
Defensive patterns

Strategy: validation

Validate before calling

// in dev, search templates for helper names used as bare named-arg values
// e.g. regex: @[\w-]+=[a-zA-Z][\w-]*$

Try / catch

try { render(); } catch (e) { if (String(e.message).includes('A resolved helper cannot be passed as a named argument')) { /* fix template syntax */ } throw e; }

Prevention

When it happens

Trigger: Using a helper name as a named argument value without invoking it, e.g. <Foo @bar=someHelper/> where someHelper resolves to a helper, in a DEBUG build.

Common situations: Migrating codebases after the paren-less helper invocation deprecation; typos omitting parentheses; addons shipping templates with legacy helper-as-argument syntax run in dev mode.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/889ebe178c951c33. Report an issue: GitHub.