diff --git a/moto/dynamodb/models/table.py b/moto/dynamodb/models/table.py
--- a/moto/dynamodb/models/table.py
+++ b/moto/dynamodb/models/table.py
@@ -848,9 +848,9 @@ def scan(
             passes_all_conditions = True
             for attribute_name in filters:
                 attribute = item.attrs.get(attribute_name)
+                (comparison_operator, comparison_objs) = filters[attribute_name]
 
                 if attribute:
-                    (comparison_operator, comparison_objs) = filters[attribute_name]
                     # Attribute found
                     if not attribute.compare(comparison_operator, comparison_objs):
                         passes_all_conditions = False

Hi @crgwbr, apologies for breaking this! Looks like there weren't any tests for this feature.

I'll raise a PR shortly with a fix (and tests this time..).
diff --git a/tests/test_dynamodb/test_dynamodb.py b/tests/test_dynamodb/test_dynamodb.py
--- a/tests/test_dynamodb/test_dynamodb.py
+++ b/tests/test_dynamodb/test_dynamodb.py
@@ -1616,6 +1616,50 @@ def test_bad_scan_filter():
     assert exc.value.response["Error"]["Code"] == "ValidationException"
 
 
+@mock_dynamodb
+def test_scan_with_scanfilter():
+    table_name = "my-table"
+    item = {"partitionKey": "pk-2", "my-attr": 42}
+    client = boto3.client("dynamodb", region_name="us-east-1")
+    res = boto3.resource("dynamodb", region_name="us-east-1")
+    res.create_table(
+        TableName=table_name,
+        KeySchema=[{"AttributeName": "partitionKey", "KeyType": "HASH"}],
+        AttributeDefinitions=[{"AttributeName": "partitionKey", "AttributeType": "S"}],
+        BillingMode="PAY_PER_REQUEST",
+    )
+    table = res.Table(table_name)
+    table.put_item(Item={"partitionKey": "pk-1"})
+    table.put_item(Item=item)
+
+    # ScanFilter: EQ
+    # The DynamoDB table-resource sends the AttributeValueList in the wrong format
+    # So this operation never finds any data, in Moto or AWS
+    table.scan(
+        ScanFilter={
+            "my-attr": {"AttributeValueList": [{"N": "42"}], "ComparisonOperator": "EQ"}
+        }
+    )
+
+    # ScanFilter: EQ
+    # If we use the boto3-client, we do receive the correct data
+    items = client.scan(
+        TableName=table_name,
+        ScanFilter={
+            "partitionKey": {
+                "AttributeValueList": [{"S": "pk-1"}],
+                "ComparisonOperator": "EQ",
+            }
+        },
+    )["Items"]
+    assert items == [{"partitionKey": {"S": "pk-1"}}]
+
+    # ScanFilter: NONE
+    # Note that we can use the table-resource here, because we're not using the AttributeValueList
+    items = table.scan(ScanFilter={"my-attr": {"ComparisonOperator": "NULL"}})["Items"]
+    assert items == [{"partitionKey": "pk-1"}]
+
+
 @mock_dynamodb
 def test_duplicate_create():
     client = boto3.client("dynamodb", region_name="us-east-1")

UnboundLocalError: cannot access local variable 'comparison_operator' where it is not associated with a value
When scanning a dynamodb table with an attribute filter that is not present on all table items, the following exception is thrown:

`UnboundLocalError: cannot access local variable 'comparison_operator' where it is not associated with a value`

This bug was introduced by the change to `moto/dynamodb/models/table.py` in commit 87f925cba5d04f361cd7dff70ade5378a9a40264. Thus, this but is present in moto 4.2.11 and 4.2.12, but is not present in 4.2.10.

The core issue is that the `elif` condition on line 858 relies on the `comparison_operator` variable, which is first defined on line 853 (within the `if` condition).

Full stack trace:

```
  File "<REDACTED>"
    scan_result = dynamodb_client.scan(
                  ^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/client.py", line 553, in _api_call
    return self._make_api_call(operation_name, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/client.py", line 989, in _make_api_call
    http, parsed_response = self._make_request(
                            ^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/client.py", line 1015, in _make_request
    return self._endpoint.make_request(operation_model, request_dict)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/endpoint.py", line 119, in make_request
    return self._send_request(request_dict, operation_model)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/endpoint.py", line 202, in _send_request
    while self._needs_retry(
          ^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/endpoint.py", line 354, in _needs_retry
    responses = self._event_emitter.emit(
                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/hooks.py", line 412, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/hooks.py", line 256, in emit
    return self._emit(event_name, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/hooks.py", line 239, in _emit
    response = handler(**kwargs)
               ^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/retryhandler.py", line 207, in __call__
    if self._checker(**checker_kwargs):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/retryhandler.py", line 284, in __call__
    should_retry = self._should_retry(
                   ^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/retryhandler.py", line 307, in _should_retry
    return self._checker(
           ^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/retryhandler.py", line 363, in __call__
    checker_response = checker(
                       ^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/retryhandler.py", line 247, in __call__
    return self._check_caught_exception(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/retryhandler.py", line 416, in _check_caught_exception
    raise caught_exception
  File "<REDACTED>/lib/python3.12/site-packages/botocore/endpoint.py", line 278, in _do_get_response
    responses = self._event_emitter.emit(event_name, request=request)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/hooks.py", line 412, in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/hooks.py", line 256, in emit
    return self._emit(event_name, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/botocore/hooks.py", line 239, in _emit
    response = handler(**kwargs)
               ^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/core/botocore_stubber.py", line 64, in __call__
    status, headers, body = response_callback(
                            ^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/core/responses.py", line 245, in dispatch
    return cls()._dispatch(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/core/responses.py", line 446, in _dispatch
    return self.call_action()
           ^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/utilities/aws_headers.py", line 46, in _wrapper
    response = f(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/utilities/aws_headers.py", line 74, in _wrapper
    response = f(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/dynamodb/responses.py", line 198, in call_action
    response = getattr(self, endpoint)()
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/dynamodb/responses.py", line 52, in _wrapper
    response = f(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/dynamodb/responses.py", line 814, in scan
    items, scanned_count, last_evaluated_key = self.dynamodb_backend.scan(
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/dynamodb/models/__init__.py", line 371, in scan
    return table.scan(
           ^^^^^^^^^^^
  File "<REDACTED>/lib/python3.12/site-packages/moto/dynamodb/models/table.py", line 858, in scan
    elif comparison_operator == "NULL":
         ^^^^^^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'comparison_operator' where it is not associated with a value
```

tests/test_dynamodb/test_dynamodb.py::test_scan_with_scanfilter
tests/test_dynamodb/test_dynamodb.py::test_remove_list_index__remove_existing_nested_index tests/test_dynamodb/test_dynamodb.py::test_basic_projection_expressions_using_query_with_attr_expression_names tests/test_dynamodb/test_dynamodb.py::test_describe_backup_for_non_existent_backup_raises_error tests/test_dynamodb/test_dynamodb.py::test_update_item_with_list tests/test_dynamodb/test_dynamodb.py::test_describe_continuous_backups_errors tests/test_dynamodb/test_dynamodb.py::test_describe_missing_table_boto3 tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_delete tests/test_dynamodb/test_dynamodb.py::test_remove_list_index__remove_existing_index tests/test_dynamodb/test_dynamodb.py::test_dynamodb_update_item_fails_on_string_sets tests/test_dynamodb/test_dynamodb.py::test_projection_expression_execution_order tests/test_dynamodb/test_dynamodb.py::test_update_item_with_attribute_in_right_hand_side_and_operation tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_conditioncheck_passes tests/test_dynamodb/test_dynamodb.py::test_basic_projection_expression_using_get_item tests/test_dynamodb/test_dynamodb.py::test_list_table_tags_empty tests/test_dynamodb/test_dynamodb.py::test_create_backup_for_non_existent_table_raises_error tests/test_dynamodb/test_dynamodb.py::test_update_expression_with_plus_in_attribute_name tests/test_dynamodb/test_dynamodb.py::test_scan_filter2 tests/test_dynamodb/test_dynamodb.py::test_describe_backup tests/test_dynamodb/test_dynamodb.py::test_batch_write_item tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_delete_with_successful_condition_expression tests/test_dynamodb/test_dynamodb.py::test_query_invalid_table tests/test_dynamodb/test_dynamodb.py::test_delete_backup tests/test_dynamodb/test_dynamodb.py::test_nested_projection_expression_using_query tests/test_dynamodb/test_dynamodb.py::test_transact_get_items_should_return_empty_map_for_non_existent_item tests/test_dynamodb/test_dynamodb.py::test_update_supports_list_append_maps tests/test_dynamodb/test_dynamodb.py::test_update_item_add_to_num_set_using_legacy_attribute_updates tests/test_dynamodb/test_dynamodb.py::test_update_supports_nested_update_if_nested_value_not_exists tests/test_dynamodb/test_dynamodb.py::test_index_with_unknown_attributes_should_fail tests/test_dynamodb/test_dynamodb.py::test_update_supports_nested_list_append tests/test_dynamodb/test_dynamodb.py::test_update_item_atomic_counter_from_zero tests/test_dynamodb/test_dynamodb.py::test_update_item_if_original_value_is_none tests/test_dynamodb/test_dynamodb.py::test_filter_expression_execution_order tests/test_dynamodb/test_dynamodb.py::test_delete_item tests/test_dynamodb/test_dynamodb.py::test_list_tables_paginated tests/test_dynamodb/test_dynamodb.py::test_query_gsi_with_range_key tests/test_dynamodb/test_dynamodb.py::test_valid_transact_get_items tests/test_dynamodb/test_dynamodb.py::test_describe_continuous_backups tests/test_dynamodb/test_dynamodb.py::test_remove_list_index__remove_existing_double_nested_index tests/test_dynamodb/test_dynamodb.py::test_non_existing_attribute_should_raise_exception tests/test_dynamodb/test_dynamodb.py::test_scan_by_non_exists_index tests/test_dynamodb/test_dynamodb.py::test_update_supports_list_append_with_nested_if_not_exists_operation tests/test_dynamodb/test_dynamodb.py::test_put_empty_item tests/test_dynamodb/test_dynamodb.py::test_gsi_lastevaluatedkey tests/test_dynamodb/test_dynamodb.py::test_query_catches_when_no_filters tests/test_dynamodb/test_dynamodb.py::test_restore_table_to_point_in_time_raises_error_when_dest_exist tests/test_dynamodb/test_dynamodb.py::test_update_supports_complex_expression_attribute_values tests/test_dynamodb/test_dynamodb.py::test_update_expression_with_numeric_literal_instead_of_value tests/test_dynamodb/test_dynamodb.py::test_list_tables_boto3[multiple-tables] tests/test_dynamodb/test_dynamodb.py::test_update_list_index__set_nested_index_out_of_range tests/test_dynamodb/test_dynamodb.py::test_update_nested_item_if_original_value_is_none tests/test_dynamodb/test_dynamodb.py::test_update_supports_multiple_levels_nested_list_append tests/test_dynamodb/test_dynamodb.py::test_list_tables_boto3[one-table] tests/test_dynamodb/test_dynamodb.py::test_put_item_nonexisting_range_key tests/test_dynamodb/test_dynamodb.py::test_list_backups tests/test_dynamodb/test_dynamodb.py::test_query_filter_overlapping_expression_prefixes tests/test_dynamodb/test_dynamodb.py::test_source_and_restored_table_items_are_not_linked tests/test_dynamodb/test_dynamodb.py::test_bad_scan_filter tests/test_dynamodb/test_dynamodb.py::test_update_expression_with_minus_in_attribute_name tests/test_dynamodb/test_dynamodb.py::test_restore_table_from_backup_raises_error_when_table_already_exists tests/test_dynamodb/test_dynamodb.py::test_put_item_nonexisting_hash_key tests/test_dynamodb/test_dynamodb.py::test_restore_table_to_point_in_time_raises_error_when_source_not_exist tests/test_dynamodb/test_dynamodb.py::test_basic_projection_expression_using_get_item_with_attr_expression_names tests/test_dynamodb/test_dynamodb.py::test_invalid_transact_get_items tests/test_dynamodb/test_dynamodb.py::test_update_continuous_backups tests/test_dynamodb/test_dynamodb.py::test_update_item_atomic_counter tests/test_dynamodb/test_dynamodb.py::test_nested_projection_expression_using_query_with_attr_expression_names tests/test_dynamodb/test_dynamodb.py::test_item_add_empty_string_range_key_exception tests/test_dynamodb/test_dynamodb.py::test_get_item_for_non_existent_table_raises_error tests/test_dynamodb/test_dynamodb.py::test_scan_filter tests/test_dynamodb/test_dynamodb.py::test_error_when_providing_expression_and_nonexpression_params tests/test_dynamodb/test_dynamodb.py::test_update_return_attributes tests/test_dynamodb/test_dynamodb.py::test_item_size_is_under_400KB tests/test_dynamodb/test_dynamodb.py::test_multiple_updates tests/test_dynamodb/test_dynamodb.py::test_scan_filter4 tests/test_dynamodb/test_dynamodb.py::test_nested_projection_expression_using_get_item_with_attr_expression tests/test_dynamodb/test_dynamodb.py::test_update_expression_with_space_in_attribute_name tests/test_dynamodb/test_dynamodb.py::test_create_multiple_backups_with_same_name tests/test_dynamodb/test_dynamodb.py::test_gsi_projection_type_keys_only tests/test_dynamodb/test_dynamodb.py::test_update_list_index__set_existing_nested_index tests/test_dynamodb/test_dynamodb.py::test_set_attribute_is_dropped_if_empty_after_update_expression[use tests/test_dynamodb/test_dynamodb.py::test_restore_table_from_non_existent_backup_raises_error tests/test_dynamodb/test_dynamodb.py::test_query_by_non_exists_index tests/test_dynamodb/test_dynamodb.py::test_gsi_key_cannot_be_empty tests/test_dynamodb/test_dynamodb.py::test_remove_list_index__remove_index_out_of_range tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_fails_with_transaction_canceled_exception tests/test_dynamodb/test_dynamodb.py::test_update_if_not_exists tests/test_dynamodb/test_dynamodb.py::test_remove_top_level_attribute tests/test_dynamodb/test_dynamodb.py::test_restore_table_from_backup tests/test_dynamodb/test_dynamodb.py::test_nested_projection_expression_using_scan_with_attr_expression_names tests/test_dynamodb/test_dynamodb.py::test_update_non_existing_item_raises_error_and_does_not_contain_item_afterwards tests/test_dynamodb/test_dynamodb.py::test_allow_update_to_item_with_different_type tests/test_dynamodb/test_dynamodb.py::test_describe_limits tests/test_dynamodb/test_dynamodb.py::test_sorted_query_with_numerical_sort_key tests/test_dynamodb/test_dynamodb.py::test_dynamodb_max_1mb_limit tests/test_dynamodb/test_dynamodb.py::test_update_continuous_backups_errors tests/test_dynamodb/test_dynamodb.py::test_list_backups_for_non_existent_table tests/test_dynamodb/test_dynamodb.py::test_duplicate_create tests/test_dynamodb/test_dynamodb.py::test_summing_up_2_strings_raises_exception tests/test_dynamodb/test_dynamodb.py::test_update_item_atomic_counter_return_values tests/test_dynamodb/test_dynamodb.py::test_put_item_with_special_chars tests/test_dynamodb/test_dynamodb.py::test_query_missing_expr_names tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_update_with_failed_condition_expression tests/test_dynamodb/test_dynamodb.py::test_describe_endpoints[eu-central-1] tests/test_dynamodb/test_dynamodb.py::test_create_backup tests/test_dynamodb/test_dynamodb.py::test_query_filter tests/test_dynamodb/test_dynamodb.py::test_list_tables_boto3[no-table] tests/test_dynamodb/test_dynamodb.py::test_attribute_item_delete tests/test_dynamodb/test_dynamodb.py::test_invalid_projection_expressions tests/test_dynamodb/test_dynamodb.py::test_delete_item_error tests/test_dynamodb/test_dynamodb.py::test_update_list_index__set_existing_index tests/test_dynamodb/test_dynamodb.py::test_nested_projection_expression_using_get_item tests/test_dynamodb/test_dynamodb.py::test_nested_projection_expression_using_scan tests/test_dynamodb/test_dynamodb.py::test_update_item_on_map tests/test_dynamodb/test_dynamodb.py::test_restore_table_to_point_in_time tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_put tests/test_dynamodb/test_dynamodb.py::test_basic_projection_expressions_using_query tests/test_dynamodb/test_dynamodb.py::test_list_not_found_table_tags tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_update tests/test_dynamodb/test_dynamodb.py::test_update_return_updated_new_attributes_when_same tests/test_dynamodb/test_dynamodb.py::test_projection_expression_with_binary_attr tests/test_dynamodb/test_dynamodb.py::test_gsi_verify_negative_number_order tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_conditioncheck_fails tests/test_dynamodb/test_dynamodb.py::test_set_ttl tests/test_dynamodb/test_dynamodb.py::test_scan_filter_should_not_return_non_existing_attributes tests/test_dynamodb/test_dynamodb.py::test_update_supports_list_append tests/test_dynamodb/test_dynamodb.py::test_put_return_attributes tests/test_dynamodb/test_dynamodb.py::test_lsi_projection_type_keys_only tests/test_dynamodb/test_dynamodb.py::test_remove_list_index__remove_multiple_indexes tests/test_dynamodb/test_dynamodb.py::test_update_list_index__set_double_nested_index tests/test_dynamodb/test_dynamodb.py::test_gsi_key_can_be_updated tests/test_dynamodb/test_dynamodb.py::test_put_item_with_streams tests/test_dynamodb/test_dynamodb.py::test_list_tables_exclusive_start_table_name_empty tests/test_dynamodb/test_dynamodb.py::test_update_item_with_no_action_passed_with_list tests/test_dynamodb/test_dynamodb.py::test_update_item_with_empty_string_attr_no_exception tests/test_dynamodb/test_dynamodb.py::test_transact_write_items_delete_with_failed_condition_expression tests/test_dynamodb/test_dynamodb.py::test_basic_projection_expressions_using_scan tests/test_dynamodb/test_dynamodb.py::test_list_table_tags tests/test_dynamodb/test_dynamodb.py::test_update_supports_nested_list_append_onto_another_list tests/test_dynamodb/test_dynamodb.py::test_update_list_index__set_index_out_of_range tests/test_dynamodb/test_dynamodb.py::test_filter_expression tests/test_dynamodb/test_dynamodb.py::test_basic_projection_expressions_using_scan_with_attr_expression_names tests/test_dynamodb/test_dynamodb.py::test_item_add_empty_string_hash_key_exception tests/test_dynamodb/test_dynamodb.py::test_item_add_empty_string_attr_no_exception tests/test_dynamodb/test_dynamodb.py::test_update_item_add_to_non_existent_set tests/test_dynamodb/test_dynamodb.py::test_gsi_projection_type_include tests/test_dynamodb/test_dynamodb.py::test_query_global_secondary_index_when_created_via_update_table_resource tests/test_dynamodb/test_dynamodb.py::test_update_item_add_to_non_existent_number_set tests/test_dynamodb/test_dynamodb.py::test_update_expression_with_multiple_set_clauses_must_be_comma_separated tests/test_dynamodb/test_dynamodb.py::test_scan_filter3 tests/test_dynamodb/test_dynamodb.py::test_update_list_index__set_index_of_a_string tests/test_dynamodb/test_dynamodb.py::test_update_supports_list_append_with_nested_if_not_exists_operation_and_property_already_exists tests/test_dynamodb/test_dynamodb.py::test_describe_endpoints[ap-south-1] tests/test_dynamodb/test_dynamodb.py::test_delete_table tests/test_dynamodb/test_dynamodb.py::test_update_item_add_to_list_using_legacy_attribute_updates tests/test_dynamodb/test_dynamodb.py::test_remove_top_level_attribute_non_existent tests/test_dynamodb/test_dynamodb.py::test_delete_non_existent_backup_raises_error tests/test_dynamodb/test_dynamodb.py::test_update_item_with_attribute_in_right_hand_side tests/test_dynamodb/test_dynamodb.py::test_list_table_tags_paginated