Error in yaml

I am having trouble compiling the attached code to Esp home, I have checked the code in variuos YAML checkers, all say it is valid. When compiling It comes up with the error :

INFO ESPHome 2026.3.3
INFO Reading configuration /config/esphome/sunroof.yaml...
Failed config
binary_sensor.gpio: [source /config/esphome/sunroof.yaml:133]

The full code is below, any help appreciated.

platform: gpio
  name: remote open
  id: remote_open
  pin: 
    number: GPIO02
    mode: INPUT_PULLUP
    inverted: True
  filters: 
    - delayed_off: 250ms
  on_press: 
    then: 
      - if: 
          condition: 
            and: 
              - binary_sensor.is_on: remote_open
              - binary_sensor.is_off: remote_close
          then: 
            - switch.turn_on: open_switch
          else: 
            
            Unable to find action with the name 'then'.
            then: 
              - script.execute: check_inputs

The full code is

switch:
  - platform: gpio
    pin: GPIO15
    restore_mode: RESTORE_DEFAULT_OFF
    id: retract_open
    interlock: &ref_0
      - retract_open
      - retract_close
  - platform: gpio
    pin: GPIO14
    restore_mode: ALWAYS_OFF
    id: retract_close
    interlock: *ref_0
  - platform: gpio
    pin: GPIO12
    restore_mode: RESTORE_DEFAULT_OFF
    id: rotate_open
    interlock: &ref_1
      - rotate_open
      - rotate_close
  - platform: gpio
    pin: GPIO13
    restore_mode: RESTORE_DEFAULT_OFF
    id: rotate_close
    interlock: *ref_1
  - platform: template
    name: Stop Switch
    id: stop_switch
    disabled_by_default: false
    restore_mode: ALWAYS_OFF
    optimistic: false
    assumed_state: false
    turn_on_action:
      - switch.turn_off: close_switch
      - switch.turn_off: open_switch
      - switch.turn_off: rotate_open
      - switch.turn_off: rotate_close
      - switch.turn_off: retract_close
      - switch.turn_off: retract_open
      - delay: 1s
      - switch.turn_off: stop_switch
      - logger.log: Stopped
  - platform: template
    name: Close Switch
    id: close_switch
    disabled_by_default: false
    restore_mode: ALWAYS_OFF
    optimistic: false
    assumed_state: false
    turn_on_action:
      then:
        - if:
            condition:
              and:
                - binary_sensor.is_off: remote_open
                - binary_sensor.is_on: remote_close
            then:
              - switch.turn_off: stop_switch
              - switch.turn_off: rotate_open
              - switch.turn_off: rotate_close
              - switch.turn_off: retract_open
              - switch.turn_on: retract_close
              - delay: 25s
              - switch.turn_off: retract_close
              - switch.turn_on: rotate_close
              - delay: 15s
              - switch.turn_off: rotate_close
              - delay: 500ms
              - switch.turn_off: close_switch
        - if:
            condition:
              - binary_sensor.is_on: rain_close
            then:
              - switch.turn_off: stop_switch
              - switch.turn_off: rotate_open
              - switch.turn_off: rotate_close
              - switch.turn_off: retract_open
              - switch.turn_on: retract_close
              - delay: 25s
              - switch.turn_off: retract_close
              - switch.turn_on: rotate_close
              - delay: 15s
              - switch.turn_off: rotate_close
              - delay: 500ms
              - switch.turn_off: close_switch
  - platform: template
    name: Open Switch
    id: open_switch
    disabled_by_default: false
    restore_mode: ALWAYS_OFF
    optimistic: false
    assumed_state: false
    turn_on_action:
      then:
        - if:
            condition:
              and:
                - binary_sensor.is_on: remote_open
                - binary_sensor.is_off: remote_close
            then:
              - switch.turn_off: stop_switch
              - switch.turn_off: rotate_open
              - switch.turn_off: rotate_close
              - switch.turn_off: retract_close
              - switch.turn_on: rotate_open
              - delay: 15s
              - switch.turn_off: rotate_open
              - switch.turn_on: retract_open
              - delay: 25s
              - switch.turn_off: retract_open
              - delay: 500ms
              - switch.turn_off: open_switch
binary_sensor:
  - platform: gpio
    name: remote open
    id: remote_open
    pin:
      number: GPIO02
      mode: INPUT_PULLUP
      inverted: true
    filters:
      - delayed_off: 250ms
    on_press:
      then:
        - if:
            condition:
              and:
                - binary_sensor.is_on: remote_open
                - binary_sensor.is_off: remote_close
            then:
              - switch.turn_on: open_switch
            else:
              then:
                - script.execute: check_inputs
  - platform: gpio
    name: Remote Close
    id: remote_close
    pin:
      number: GPIO04
      mode: INPUT_PULLUP
      inverted: true
    filters:
      - delayed_off: 250ms
    on_press:
      then:
        - if:
            condition:
              and:
                - binary_sensor.is_off: remote_open
                - binary_sensor.is_on: remote_close
            then:
              - switch.turn_on: close_switch
            else:
              then:
                - script.execute: check_inputs
  - platform: gpio
    name: rain close
    id: rain_close
    pin:
      number: GPIO05
      mode: INPUT_PULLUP
      inverted: true
    filters:
      - delayed_off: 250ms
    on_press:
      then:
        - switch.turn_on: close_switch
script:
  - id: check_inputs
    then:
      - if:
          condition:
            and:
              - binary_sensor.is_off: remote_close
              - binary_sensor.is_off: remote_open
          then:
            - switch.turn_on: stop_switch

Remove then: - that’s not a valid syntax:

        - if:
            condition:
              and:
                - binary_sensor.is_off: remote_open
                - binary_sensor.is_on: remote_close
            then:
              - switch.turn_on: close_switch
            else:
              - script.execute: check_inputs

Thanks for that missed that mistake. Funny how online checkers missed it too.

What you had was valid YAML in that the structure was correct. That’s all the online checkers are checking. Just because it’s valid YAML doesn’t mean it’s a valid ESPHome YAML file.