AUR9998

Error Message

AUR9998: Spread binding does not support spreading custom attributes/template controllers. Did you build the spread instruction manually?

Description

This error occurs when the Aurelia template compiler encounters an attempt to use spread binding syntax (...) with template controllers (like if, repeat, switch) or custom attributes that are not meant to be spread. The spread binding feature in Aurelia is designed specifically for spreading bindable properties onto custom elements, not for template controllers or certain types of custom attributes.

Cause

This error typically happens when:

  1. Spreading Template Controllers: Attempting to spread template controllers like if, repeat, switch, etc.

  2. Spreading Non-Bindable Attributes: Trying to spread custom attributes that don't support being spread

  3. Manual Instruction Building: Manually constructing spread instructions in a way that's not supported by the template compiler

  4. Invalid Spread Syntax: Using spread syntax in contexts where it's not allowed

Common Scenarios

❌ Incorrect: Spreading Template Controllers

<!-- This will throw AUR9998 -->
<template>
  <div ...="templateControllerProps"></div>
</template>
export class MyComponent {
  templateControllerProps = {
    'if.bind': 'showElement',
    'repeat.for': 'item of items'
  };
}

❌ Incorrect: Spreading Custom Attributes

<!-- This might throw AUR9998 depending on the attribute -->
<template>
  <div ...="customAttributeProps"></div>
</template>
export class MyComponent {
  customAttributeProps = {
    'my-custom-attribute.bind': 'someValue'
  };
}

Solution

1. Use Spread Only for Bindable Properties

Spread binding should only be used to spread bindable properties of custom elements:

<!-- ✅ Correct: Spreading bindables onto a custom element -->
<template>
  <my-custom-element ...="elementProps"></my-custom-element>
</template>
export class MyComponent {
  elementProps = {
    'title.bind': 'pageTitle',
    'visible.bind': 'isVisible',
    'data.bind': 'componentData'
  };
}

2. Use Template Controllers Directly

Instead of trying to spread template controllers, use them directly:

<!-- ✅ Correct: Use template controllers directly -->
<template>
  <div if.bind="showElement">Content shown conditionally</div>
  <div repeat.for="item of items">${item.name}</div>
</template>

3. Use Individual Bindings for Custom Attributes

For custom attributes, bind them individually rather than spreading:

<!-- ✅ Correct: Individual custom attribute bindings -->
<template>
  <div my-custom-attribute.bind="someValue"
       another-attribute.bind="anotherValue">
    Content
  </div>
</template>

4. Check Your Custom Element Definition

Ensure your custom element properly defines bindable properties:

import { bindable, customElement } from '@aurelia/runtime-html';

@customElement({
  name: 'my-custom-element',
  template: '<div>${title}</div>'
})
export class MyCustomElement {
  @bindable title: string;
  @bindable visible: boolean;
  @bindable data: unknown;
}

Example: Correct Usage

<!-- my-app.html -->
<template>
  <!-- ✅ Correct: Spreading bindables to custom elements -->
  <user-card ...="userProps"></user-card>
  
  <!-- ✅ Correct: Template controllers used directly -->
  <div if.bind="showUserList">
    <user-card repeat.for="user of users" ...="user"></user-card>
  </div>
</template>
import { customElement } from '@aurelia/runtime-html';

@customElement({
  name: 'my-app',
  template: '...' // template from above
})
export class MyApp {
  users = [
    { name: 'John', email: '[email protected]', active: true },
    { name: 'Jane', email: '[email protected]', active: false }
  ];

  userProps = {
    'name.bind': 'currentUser.name',
    'email.bind': 'currentUser.email',
    'active.bind': 'currentUser.active'
  };

  showUserList = true;
  currentUser = this.users[0];
}

Debugging Tips

  1. Check Spread Target: Ensure you're only spreading onto custom elements, not regular HTML elements or template controllers

  2. Verify Bindable Properties: Make sure all properties in your spread object correspond to actual @bindable properties on the target custom element

  3. Review Template Structure: Look for any template controllers (if, repeat, switch) that might be accidentally included in spread objects

  4. Check Manual Instructions: If you're manually building template instructions, ensure you're not creating spread instructions for unsupported scenarios

Last updated

Was this helpful?