       i += consumed
 
     if @activeBranchNode()? and @activeBranchNode() isnt @parseTree
-      message = "Unexpected end of input: unclosed #{@activeBranchNode().type}"
+      message = "Unexpected end of input: unclosed #{@currentState()}"
       throwSyntaxError message, first_line: @chunkLine, first_column: @chunkColumn
 
     @remainder = code[i..]

  # parseTree helpers

  activeBranchNode: -> last(@activeStates)

  newestNode: -> last(@activeBranchNode().children) or @activeBranchNode()


    return 0 unless selfClosing or @chunk.indexOf("</#{tagName}>", input.length) > -1

    @pushActiveBranchNode parseTreeBranchNode $.CJSX_EL, tagName
    # @pushActiveBranchNode parseTreeBranchNode $.CJSX_ATTRIBUTES
    @addLeafNodeToActiveBranch @cjsxAttributesParse attributesText

    if selfClosing
      @popActiveBranchNode() # close cjsx tag

    # 1+tagName.length
    input.length

  cjsxAttribute: ->
    return 0 unless @currentState() is $.CJSX_ATTRIBUTES

    if @chunk.charAt(0) is '/'
      if @chunk.charAt(1) is '>'
        @popActiveBranchNode() # end attributes
        @popActiveBranchNode() # end cjsx
        return 2
      else
        throwSyntaxError \
          "/ without immediately following > in CJSX tag #{@peekActiveState(2).value}",
          first_line: @chunkLine, first_column: @chunkColumn

    if @chunk.charAt(0) is '>'
      @popActiveBranchNode() # end attributes
      return 1



  cjsxAttrKey: ->
    return 0 unless @currentState() is $.CJSX_ATTRIBUTES

  cjsxEscape: ->
    return 0 unless @currentState() is $.CJSX_EL and @chunk.charAt(0) is '{'

    @pushActiveBranchNode parseTreeBranchNode $.CJSX_ESC
    return 1

  cjsxUnescape: ->
    return 0 if @opts.contained
    return 0 unless @currentState() is $.CJSX_ESC and @chunk.charAt(0) is '}'

    @popActiveBranchNode() # close cjsx escape
    return 1

  cjsxEnd: ->
    return 0 unless @currentState() is $.CJSX_EL
    return 0 unless match = CLOSING_TAG.exec @chunk
    [input, tagName] = match

