googleapis/mcp-toolbox · error
unable to execute DML statement: %w
Error message
unable to execute DML statement: %w
What it means
Returned by Source.RunSQL when a non-readOnly statement is executed with ExecContext and the Oracle driver reports an execution error. The statement reached the database (or attempted to) but failed to execute — SQL syntax errors, ORA-xxxxx errors, permission errors, or connection drops are wrapped here. It applies to INSERT/UPDATE/DELETE/DDL/PL-SQL executed through the execute-sql tool path.
Source
Thrown at internal/sources/oracle/oracle.go:149
}
func (s *Source) SourceType() string {
return SourceType
}
func (s *Source) ToConfig() sources.SourceConfig {
return s.Config
}
func (s *Source) OracleDB() *sql.DB {
return s.DB
}
func (s *Source) RunSQL(ctx context.Context, statement string, params []any, readOnly bool) (any, error) {
if !readOnly {
result, err := s.OracleDB().ExecContext(ctx, statement, params...)
if err != nil {
return nil, fmt.Errorf("unable to execute DML statement: %w", err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return nil, fmt.Errorf("unable to get rows affected: %w", err)
}
return map[string]any{
"status": "success",
"rows_affected": rowsAffected,
}, nil
}
rows, err := s.OracleDB().QueryContext(ctx, statement, params...)
if err != nil {
return nil, fmt.Errorf("unable to execute query: %w", err)
}
defer rows.Close()
View on GitHub (pinned to 8cc6e09de2)
Solutions
- Inspect the wrapped ORA-xxxxx code; look up its meaning (e.g. ORA-00911 → remove trailing semicolon or invalid characters).
- Run the exact statement in SQL Developer/sqlplus as the same user to confirm it is valid SQL, not a driver issue.
- Verify the connected user has the required object privileges (SELECT/INSERT/etc.) and the object is schema-qualified if needed.
- Check that the number of ? placeholders matches len(params).
- If it was a transient network error, verify connectivity and retry the statement.
Example fix
// before (LLM sent trailing semicolon → ORA-00911) statement: "UPDATE employees SET salary = salary * 1.1;" // after statement: "UPDATE employees SET salary = salary * 1.1"
Defensive patterns
Strategy: try-catch
Validate before calling
// strip trailing semicolons and empty statements before invoking RunSQL
stmt := strings.TrimSpace(statement)
stmt = strings.TrimSuffix(stmt, ";")
if stmt == "" {
return fmt.Errorf("empty statement")
} Type guard
func isDMLExecError(err error) bool {
return err != nil && strings.Contains(err.Error(), "unable to execute DML statement")
} Try / catch
result, err := src.RunSQL(ctx, stmt, params, false)
if err != nil {
if isDMLExecError(err) {
var oraCode string
if m := regexp.MustCompile(`ORA-\d{5}`).FindStringSubmatch(err.Error()); m != nil {
oraCode = m[0]
}
log.Printf("DML failed (%s): %v", oraCode, err)
return fmt.Errorf("statement rejected by oracle (%s): %w", oraCode, err)
}
return err
} Prevention
- Strip trailing semicolons from tool-supplied SQL (Oracle rejects them with ORA-00911).
- Grant the toolbox user only the privileges it needs on exactly the intended objects.
- Count placeholders and parameters before executing parameterized statements.
- Log the wrapped ORA-xxxxx code for every failure to speed up diagnosis.
When it happens
Trigger: RunSQL(ctx, statement, params, readOnly=false) calling s.OracleDB().ExecContext where the driver returns an error: ORA-00942 table or view does not exist, ORA-00911 invalid character (e.g. trailing semicolon), ORA-01013 user requested cancel, ORA-01031 insufficient privileges, or parameter count/type mismatch.
Common situations: LLM-generated SQL containing a trailing semicolon (ORA-00911); querying a table without schema qualification or grants; referencing a dropped/renamed table; sending a parameterized statement with wrong number of placeholders; session killed by DBA or network interruption mid-execution.
Related errors
- unable to get rows affected: %w
- unable to execute query: %w
- unable to execute query: %w
- unable to parse row: %w
- unable to execute query: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/1edefc7401020ea0.
Report an issue: GitHub.