> For the complete documentation index, see [llms.txt](https://docs.aurelia.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aurelia.io/developer-guides/error-messages/runtime-html/aur0772.md).

# AUR0772

## Error Message

`AUR0772: Invalid @watch decorator config. Expected an expression or a fn but received null/undefined.`

## Description

This error occurs when using the `@watch` decorator, but the required first argument (the expression to watch) is `null` or `undefined`. The `@watch` decorator needs a valid target to observe for changes.

## Cause

The primary cause is providing `null` or `undefined` as the first argument to the `@watch` decorator.

```typescript
import { watch } from '@aurelia/runtime-html';

export class MyViewModel {
  // Incorrect: Passing null as the expression
  @watch(null)
  nullWatchHandler() { /* ... */ }

  // Incorrect: Passing undefined as the expression
  @watch(undefined)
  undefinedWatchHandler() { /* ... */ }

  // Incorrect: Passing a variable that is null/undefined
  @watch(someVariableThatMightBeNull)
  variableWatchHandler() { /* ... */ }
}
```

## Solution

Ensure that the first argument provided to the `@watch` decorator is always a valid string representing the property path or expression to watch, or a function that selects the value to watch.

1. **Provide a Valid Expression:** Replace `null` or `undefined` with a string expression (e.g., `'myProperty'`, `'user.address.street'`) or a function.
2. **Check Variables:** If using a variable for the expression, ensure it holds a valid string or function before being used in the decorator. Decorator arguments are evaluated at class definition time.

## Example

```typescript
import { watch } from '@aurelia/runtime-html';
import { IContainer, ILogger } from '@aurelia/kernel';

export class MyViewModel {
  private readonly logger = resolve(ILogger);
  firstName: string = 'John';
  lastName: string = 'Doe';
  address: { street: string, city: string } = { street: '123 Main St', city: 'Anytown' };

  // Correct: Watching a simple property using a string
  @watch('firstName')
  firstNameChanged(newValue: string, oldValue: string) {
    this.logger.info(`First name changed from ${oldValue} to ${newValue}`);
  }

  // Correct: Watching a nested property using a string path
  @watch('address.street')
  streetChanged(newValue: string, oldValue: string) {
    this.logger.info(`Street changed from ${oldValue} to ${newValue}`);
  }

  // Correct: Watching an expression using a function
  @watch((vm: MyViewModel) => vm.firstName + ' ' + vm.lastName)
  fullNameChanged(newValue: string, oldValue: string) {
    this.logger.info(`Full name changed from ${oldValue} to ${newValue}`);
  }

  // Correct: Watching multiple properties via a function returning an array
  @watch((vm: MyViewModel) => [vm.address.street, vm.address.city])
  addressChanged(newValues: [string, string], oldValues: [string, string]) {
    this.logger.info(`Address parts changed from ${oldValues?.join(', ')} to ${newValues.join(', ')}`);
  }

  // Incorrect examples that would cause AUR0772:
  // @watch(null)
  // invalidNullHandler() { /* ... */ }

  // @watch(undefined)
  // invalidUndefinedHandler() { /* ... */ }
}

```

## Debugging Tips

* Verify the arguments passed to the `@watch` decorator directly in your component's code.
* Ensure any variables used as arguments to `@watch` are defined and have the correct type (string or function) at the time the class is defined. Remember that decorator code runs early in the class definition process.

```
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.aurelia.io/developer-guides/error-messages/runtime-html/aur0772.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
