@@ -1405,7 +1405,15 @@ func (c *Client) executeRPC(ctx context.Context, req *Req) (Res, error) {
14051405 rpcXML := c .buildEditConfigXML (req )
14061406 scrapligoRes , err = c .driver .RPC (opoptions .WithFilter (rpcXML ))
14071407 } else {
1408- scrapligoRes , err = c .driver .EditConfig (req .Target , req .Config )
1408+ // For standard edit-config, ensure config has <config> wrapper
1409+ // scrapligo's EditConfig expects the caller to provide the config element
1410+ configContent := req .Config
1411+ result := xmldot .Get (req .Config , "config" )
1412+ if ! result .Exists () {
1413+ // Config doesn't have <config> wrapper, add it
1414+ configContent = "<config>" + req .Config + "</config>"
1415+ }
1416+ scrapligoRes , err = c .driver .EditConfig (req .Target , configContent )
14091417 }
14101418
14111419 case "copy-config" :
@@ -1636,6 +1644,11 @@ func (c *Client) parseRPCErrors(responseXML string) []ErrorModel {
16361644// This method constructs the full edit-config RPC according to RFC 6241 Section 7.2,
16371645// including optional default-operation, test-option, and error-option elements.
16381646//
1647+ // Per RFC 6241, the <config> element in edit-config should contain the configuration
1648+ // data directly, not wrapped in another <config> element. If the caller provides
1649+ // configuration with an outer <config> wrapper (e.g., from Body builder), this method
1650+ // extracts the inner content automatically.
1651+ //
16391652// Uses xmldot for safe XML building with automatic escaping.
16401653//
16411654// Returns the complete RPC XML string.
@@ -1661,8 +1674,24 @@ func (c *Client) buildEditConfigXML(req *Req) string {
16611674 xml , _ = xmldot .Set (xml , "edit-config.error-option" , req .ErrorOption ) //nolint:errcheck // XML building errors caught during validation
16621675 }
16631676
1664- // Config data (raw XML content)
1665- xml , _ = xmldot .SetRaw (xml , "edit-config.config" , req .Config ) //nolint:errcheck // XML building errors caught during validation
1677+ // Extract config content - strip outer <config> wrapper if present
1678+ // Per RFC 6241, edit-config's <config> element should contain the configuration
1679+ // data directly, not wrapped in another <config> element
1680+ configContent := req .Config
1681+
1682+ // Check if user provided <config>...</config> wrapper and extract inner content
1683+ result := xmldot .Get (req .Config , "config" )
1684+ if result .Exists () {
1685+ // User provided <config> wrapper (e.g., from Body builder), extract inner XML content
1686+ // Use |@raw modifier to get the raw inner XML without the <config> wrapper
1687+ innerContent := xmldot .Get (req .Config , "config|@raw" ).String ()
1688+ if innerContent != "" {
1689+ configContent = innerContent
1690+ }
1691+ }
1692+
1693+ // Config data (raw XML content without outer <config> wrapper)
1694+ xml , _ = xmldot .SetRaw (xml , "edit-config.config" , configContent ) //nolint:errcheck // XML building errors caught during validation
16661695
16671696 return xml
16681697}
0 commit comments