Summary
When using ruby-jss with rexml 3.4.4 or 3.4.3, I encountered a REXML::ParseException when attempting to call save on a Group object.
The error message indicates that the XML being parsed is malformed due to the absence of a root element. This appears to be related to changes in how REXML validates XML documents.
Environment
- Ruby version: 3.4.6
- ruby-jss: 4.2.3
- rexml versions tested:
- 3.4.4 ❌ (fails)
- 3.4.3 ❌ (fails)
- 3.4.2 ✅ (works as expected)
- OS: macOS
Expected Behavior
ComputerGroup#save should successfully update the group with added members.
Actual Behavior
The method call fails with a REXML::ParseException indicating "Malformed XML: No root element".
Steps to Reproduce
test.rb
#!/usr/bin/env ruby
require 'ruby-jss'
params = {
host: 'server.example.com',
client_id: ENV['CLIENT_ID'],
client_secret: ENV['CLIENT_SECRET'],
}
Jamf.cnx.connect(**params)
id = 131 # example group ID
computer_group = Jamf::ComputerGroup.fetch(id)
computer_group.add_member `hostname`.strip
computer_group.save # 🔥 This line throws the exception
Gemfile
source 'https://rubygems.org'
gem 'ruby-jss'
gem 'rexml', '<version>' # Change version to test different behaviors
Error Stack Trace
/path/to/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb:271:in 'REXML::Parsers::BaseParser#pull_event': Malformed XML: No root element (REXML::ParseException)
Line: 1
Position: 54
Last 80 unconsumed characters:
from /path/to/gems/rexml-3.4.4/lib/rexml/parsers/baseparser.rb:249:in 'REXML::Parsers::BaseParser#pull'
from /path/to/gems/rexml-3.4.4/lib/rexml/parsers/treeparser.rb:21:in 'REXML::Parsers::TreeParser#parse'
from /path/to/gems/rexml-3.4.4/lib/rexml/document.rb:468:in 'REXML::Document#build'
from /path/to/gems/rexml-3.4.4/lib/rexml/document.rb:105:in 'REXML::Document#initialize'
from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:509:in 'Class#new'
from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:509:in 'Jamf::Group#rest_xml'
from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/api_objects/updatable.rb:97:in 'Jamf::Updatable#update_in_jamf'
from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/api_object.rb:1340:in 'Jamf::APIObject#update'
from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:274:in 'Jamf::Group#update'
from /path/to/gems/ruby-jss-4.2.3/lib/jamf/api/classic/base_classes/group.rb:288:in 'Jamf::Group#save'
from main.rb:20:in '<main>'
Problematic Code
The issue appears to be in lib/jamf/api/classic/base_classes/group.rb:509:
def rest_xml
doc = REXML::Document.new Jamf::Connection::XML_HEADER # This line causes the exception
group = doc.add_element self.class::RSRC_OBJECT_KEY.to_s
# ...
end
Root Cause Analysis
This exception appears to be caused by recent changes in REXML.
It seems that the exception started occurring after the change introduced in Reject no root element XML as an invalid XML by naitoh · Pull Request #291 · ruby/rexml, which rejects XML documents without a root element as invalid.
The XML_HEADER content may need to be adjusted to ensure it contains a valid root element before being passed to REXML::Document.new.
Workaround
Currently, the only workaround is to downgrade to rexml 3.4.2 which doesn't enforce this validation.
I'm happy to assist with testing any potential fixes. Please let me know if you need any additional information.
Summary
When using ruby-jss with rexml 3.4.4 or 3.4.3, I encountered a REXML::ParseException when attempting to call
saveon a Group object.The error message indicates that the XML being parsed is malformed due to the absence of a root element. This appears to be related to changes in how REXML validates XML documents.
Environment
Expected Behavior
ComputerGroup#saveshould successfully update the group with added members.Actual Behavior
The method call fails with a REXML::ParseException indicating "Malformed XML: No root element".
Steps to Reproduce
test.rb
Gemfile
Error Stack Trace
Problematic Code
The issue appears to be in
lib/jamf/api/classic/base_classes/group.rb:509:Root Cause Analysis
This exception appears to be caused by recent changes in REXML.
It seems that the exception started occurring after the change introduced in Reject no root element XML as an invalid XML by naitoh · Pull Request #291 · ruby/rexml, which rejects XML documents without a root element as invalid.
The XML_HEADER content may need to be adjusted to ensure it contains a valid root element before being passed to REXML::Document.new.
Workaround
Currently, the only workaround is to downgrade to rexml 3.4.2 which doesn't enforce this validation.
I'm happy to assist with testing any potential fixes. Please let me know if you need any additional information.