Index: app/xcf/xcf.c
===================================================================
--- app/xcf/xcf.c	(revision 26581)
+++ app/xcf/xcf.c	(working copy)
@@ -330,7 +330,8 @@ xcf_load_invoker (GimpProcedure      *pr
                    gimp_filename_to_utf8 (filename), g_strerror (save_errno));
     }
 
-  return_vals = gimp_procedure_get_return_values (procedure, success);
+  return_vals = gimp_procedure_get_return_values (procedure, success,
+                                                  error ? *error : NULL);
 
   if (success)
     gimp_value_set_image (&return_vals->values[1], image);
@@ -422,7 +423,8 @@ xcf_save_invoker (GimpProcedure      *pr
                    gimp_filename_to_utf8 (filename), g_strerror (save_errno));
     }
 
-  return_vals = gimp_procedure_get_return_values (procedure, success);
+  return_vals = gimp_procedure_get_return_values (procedure, success,
+                                                  error ? *error : NULL);
 
   gimp_unset_busy (gimp);
 
Index: app/plug-in/gimppluginprocframe.c
===================================================================
--- app/plug-in/gimppluginprocframe.c	(revision 26581)
+++ app/plug-in/gimppluginprocframe.c	(working copy)
@@ -173,7 +173,7 @@ gimp_plug_in_proc_frame_get_return_vals 
         {
           /* Allocate new return values of the correct size. */
           return_vals = gimp_procedure_get_return_values (proc_frame->procedure,
-                                                          FALSE);
+                                                          TRUE, NULL);
 
           /* Copy all of the arguments we can. */
           memcpy (return_vals->values, proc_frame->return_vals->values,
@@ -191,9 +191,9 @@ gimp_plug_in_proc_frame_get_return_vals 
     }
   else
     {
-      /* Just return a dummy set of values. */
+      /*  Assume an execution error.  */
       return_vals = gimp_procedure_get_return_values (proc_frame->procedure,
-                                                      FALSE);
+                                                      FALSE, NULL);
     }
 
   return return_vals;
Index: app/plug-in/gimppluginmanager-call.c
===================================================================
--- app/plug-in/gimppluginmanager-call.c	(revision 26581)
+++ app/plug-in/gimppluginmanager-call.c	(working copy)
@@ -41,6 +41,7 @@
 #include "gimpplugin.h"
 #include "gimpplugin-message.h"
 #include "gimpplugindef.h"
+#include "gimppluginerror.h"
 #include "gimppluginmanager.h"
 #define __YES_I_NEED_GIMP_PLUG_IN_MANAGER_CALL__
 #include "gimppluginmanager-call.h"
@@ -140,7 +141,6 @@ gimp_plug_in_manager_call_run (GimpPlugI
                                GimpPlugInProcedure *procedure,
                                GValueArray         *args,
                                gboolean             synchronous,
-                               gboolean             destroy_return_vals,
                                GimpObject          *display)
 {
   GValueArray *return_vals = NULL;
@@ -167,8 +167,19 @@ gimp_plug_in_manager_call_run (GimpPlugI
 
       if (! gimp_plug_in_open (plug_in, GIMP_PLUG_IN_CALL_RUN, FALSE))
         {
+          const gchar *name  = gimp_object_get_name (GIMP_OBJECT (plug_in));
+          GError      *error = g_error_new (GIMP_PLUG_IN_ERROR,
+                                            GIMP_PLUG_IN_EXECUTION_FAILED,
+                                            _("Failed to run plug-in \"%s\""),
+                                            name);
+
           g_object_unref (plug_in);
-          goto done;
+
+          return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
+                                                          FALSE, error);
+          g_error_free (error);
+
+          return return_vals;
         }
 
       display_ID = display ? gimp_get_display_ID (manager->gimp, display) : -1;
@@ -206,14 +217,22 @@ gimp_plug_in_manager_call_run (GimpPlugI
           ! gp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
           ! gimp_wire_flush (plug_in->my_write, plug_in))
         {
+          const gchar *name  = gimp_object_get_name (GIMP_OBJECT (plug_in));
+          GError      *error = g_error_new (GIMP_PLUG_IN_ERROR,
+                                            GIMP_PLUG_IN_EXECUTION_FAILED,
+                                            _("Failed to run plug-in \"%s\""),
+                                            name);
+
           g_free (config.display_name);
           g_free (proc_run.params);
 
-          return_vals =
-            gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure), FALSE);
-
           g_object_unref (plug_in);
-          goto done;
+
+          return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
+                                                          FALSE, error);
+          g_error_free (error);
+
+          return return_vals;
         }
 
       g_free (config.display_name);
@@ -260,13 +279,6 @@ gimp_plug_in_manager_call_run (GimpPlugI
       g_object_unref (plug_in);
     }
 
- done:
-  if (return_vals && destroy_return_vals)
-    {
-      g_value_array_free (return_vals);
-      return_vals = NULL;
-    }
-
   return return_vals;
 }
 
@@ -277,8 +289,7 @@ gimp_plug_in_manager_call_run_temp (Gimp
                                     GimpTemporaryProcedure *procedure,
                                     GValueArray            *args)
 {
-  GValueArray *return_vals = NULL;
-  GimpPlugIn  *plug_in;
+  GimpPlugIn *plug_in;
 
   g_return_val_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
@@ -291,6 +302,7 @@ gimp_plug_in_manager_call_run_temp (Gimp
   if (plug_in)
     {
       GimpPlugInProcFrame *proc_frame;
+      GValueArray         *return_vals;
       GPProcRun            proc_run;
 
       proc_frame = gimp_plug_in_proc_frame_push (plug_in, context, progress,
@@ -303,13 +315,20 @@ gimp_plug_in_manager_call_run_temp (Gimp
       if (! gp_temp_proc_run_write (plug_in->my_write, &proc_run, plug_in) ||
           ! gimp_wire_flush (plug_in->my_write, plug_in))
         {
+          const gchar *name  = gimp_object_get_name (GIMP_OBJECT (plug_in));
+          GError      *error = g_error_new (GIMP_PLUG_IN_ERROR,
+                                            GIMP_PLUG_IN_EXECUTION_FAILED,
+                                            _("Failed to run plug-in \"%s\""),
+                                            name);
+
           g_free (proc_run.params);
           gimp_plug_in_proc_frame_pop (plug_in);
 
-          return_vals =
-            gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure), FALSE);
+          return_vals = gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
+                                                          FALSE, error);
+          g_error_free (error);
 
-          goto done;
+          return return_vals;
         }
 
       g_free (proc_run.params);
@@ -327,8 +346,13 @@ gimp_plug_in_manager_call_run_temp (Gimp
 
       gimp_plug_in_proc_frame_unref (proc_frame, plug_in);
       g_object_unref (plug_in);
-    }
 
- done:
-  return return_vals;
+      return return_vals;
+    }
+  else
+    {
+      /*  can we actually ever get here?  */
+      return gimp_procedure_get_return_values (GIMP_PROCEDURE (procedure),
+                                               FALSE, NULL);
+    }
 }
Index: app/plug-in/gimppluginmanager-call.h
===================================================================
--- app/plug-in/gimppluginmanager-call.h	(revision 26581)
+++ app/plug-in/gimppluginmanager-call.h	(working copy)
@@ -46,7 +46,6 @@ GValueArray * gimp_plug_in_manager_call_
                                                   GimpPlugInProcedure    *procedure,
                                                   GValueArray            *args,
                                                   gboolean                synchronous,
-                                                  gboolean                destroy_return_vals,
                                                   GimpObject             *display);
 
 /*  Run a temp plug-in proc as if it were a procedure database procedure
Index: app/plug-in/gimpplugin-progress.c
===================================================================
--- app/plug-in/gimpplugin-progress.c	(revision 26581)
+++ app/plug-in/gimpplugin-progress.c	(working copy)
@@ -30,12 +30,15 @@
 #include "core/gimpprogress.h"
 
 #include "pdb/gimppdb.h"
+#include "pdb/gimppdberror.h"
 
 #include "gimpplugin.h"
 #include "gimpplugin-progress.h"
 #include "gimppluginmanager.h"
 #include "gimptemporaryprocedure.h"
 
+#include "gimp-intl.h"
+
 
 /*  local function prototypes  */
 
@@ -326,10 +329,13 @@ gimp_plug_in_progress_cancel_callback (G
 
   if (proc_frame->main_loop)
     {
-      proc_frame->return_vals = gimp_procedure_get_return_values (NULL,
-                                                                  FALSE);
+      GError *error = g_error_new (GIMP_PDB_ERROR, GIMP_PDB_CALL_CANCELLED,
+                                   "%s", _("Cancelled"));
+
+      proc_frame->return_vals =
+        gimp_procedure_get_return_values (proc_frame->procedure, FALSE, error);
 
-      g_value_set_enum (proc_frame->return_vals->values, GIMP_PDB_CANCEL);
+      g_error_free (error);
     }
 
   for (list = plug_in->temp_proc_frames; list; list = g_list_next (list))
@@ -338,8 +344,12 @@ gimp_plug_in_progress_cancel_callback (G
 
       if (proc_frame->main_loop)
         {
-          proc_frame->return_vals = gimp_procedure_get_return_values (NULL,
-                                                                      FALSE);
+          GError *error = g_error_new (GIMP_PDB_ERROR, GIMP_PDB_CALL_CANCELLED,
+                                       "%s", _("Cancelled"));
+
+          proc_frame->return_vals =
+            gimp_procedure_get_return_values (proc_frame->procedure,
+                                              FALSE, error);
 
           g_value_set_enum (proc_frame->return_vals->values, GIMP_PDB_CANCEL);
         }
Index: app/plug-in/gimppluginprocedure.c
===================================================================
--- app/plug-in/gimppluginprocedure.c	(revision 26581)
+++ app/plug-in/gimppluginprocedure.c	(working copy)
@@ -212,7 +212,7 @@ gimp_plug_in_procedure_execute (GimpProc
   return gimp_plug_in_manager_call_run (gimp->plug_in_manager,
                                         context, progress,
                                         GIMP_PLUG_IN_PROCEDURE (procedure),
-                                        args, TRUE, FALSE, NULL);
+                                        args, TRUE, NULL);
 }
 
 static void
@@ -223,10 +223,19 @@ gimp_plug_in_procedure_execute_async (Gi
                                       GValueArray   *args,
                                       GimpObject    *display)
 {
-  gimp_plug_in_manager_call_run (gimp->plug_in_manager,
-                                 context, progress,
-                                 GIMP_PLUG_IN_PROCEDURE (procedure),
-                                 args, FALSE, TRUE, display);
+  GimpPlugInProcedure *plug_in_procedure = GIMP_PLUG_IN_PROCEDURE (procedure);
+  GValueArray         *return_vals;
+
+  return_vals = gimp_plug_in_manager_call_run (gimp->plug_in_manager,
+                                               context, progress,
+                                               plug_in_procedure,
+                                               args, FALSE, display);
+
+  /*  In case of errors, gimp_plug_in_manager_call_run() may return
+   *  return_vals, even if run asynchronously.
+   */
+  if (return_vals)
+    g_value_array_free (return_vals);
 }
 
 const gchar *
Index: tools/pdbgen/app.pl
===================================================================
--- tools/pdbgen/app.pl	(revision 26581)
+++ tools/pdbgen/app.pl	(working copy)
@@ -130,7 +130,7 @@ sub marshal_outargs {
     my $proc = shift;
 
     my $result = <<CODE;
-  return_vals = gimp_procedure_get_return_values (procedure, success);
+  return_vals = gimp_procedure_get_return_values (procedure, success, *error);
 CODE
 
     my $argc = 0;
@@ -183,7 +183,7 @@ CODE
 	}
     }
 
-    $result =~ s/, success\);$/, TRUE);/m unless $success;
+    $result =~ s/, success, \*error\);$/, TRUE, NULL);/m unless $success;
     $result;
 }
 
Index: tools/pdbgen/pdb/fileops.pdb
===================================================================
--- tools/pdbgen/pdb/fileops.pdb	(revision 26581)
+++ tools/pdbgen/pdb/fileops.pdb	(working copy)
@@ -63,7 +63,7 @@ HELP
                                     error);
 
   if (! uri)
-    return gimp_procedure_get_return_values (procedure, FALSE);
+    return gimp_procedure_get_return_values (procedure, FALSE, *error);
 
   file_proc =
     file_procedure_find (gimp->plug_in_manager->load_procs, uri, error);
@@ -71,7 +71,7 @@ HELP
   g_free (uri);
 
   if (! file_proc)
-    return gimp_procedure_get_return_values (procedure, FALSE);
+    return gimp_procedure_get_return_values (procedure, FALSE, *error);
 
   proc = GIMP_PROCEDURE (file_proc);
 
@@ -276,7 +276,7 @@ HELP
                                     error);
 
   if (! uri)
-    return gimp_procedure_get_return_values (procedure, FALSE);
+    return gimp_procedure_get_return_values (procedure, FALSE, *error);
 
   file_proc =
     file_procedure_find (gimp->plug_in_manager->save_procs, uri, error);
@@ -284,7 +284,7 @@ HELP
   g_free (uri);
 
   if (! file_proc)
-    return gimp_procedure_get_return_values (procedure, FALSE);
+    return gimp_procedure_get_return_values (procedure, FALSE, *error);
 
   proc = GIMP_PROCEDURE (file_proc);
 
Index: plug-ins/pygimp/pygimp-pdb.c
===================================================================
--- plug-ins/pygimp/pygimp-pdb.c	(revision 26581)
+++ plug-ins/pygimp/pygimp-pdb.c	(working copy)
@@ -929,8 +929,11 @@ pf_call(PyGimpPDBFunction *self, PyObjec
 #if PG_DEBUG > 0
 	g_printerr("execution error\n");
 #endif
+        if (ret[1].type == GIMP_PDB_STRING)
+	  PyErr_SetString(PyExc_RuntimeError, ret[1].data.d_string);
+        else
+          PyErr_SetString(PyExc_RuntimeError, "execution error");
 	gimp_destroy_params(ret, nret);
-	PyErr_SetString(PyExc_RuntimeError, "execution error");
 	return NULL;
 	break;
 
@@ -938,8 +941,11 @@ pf_call(PyGimpPDBFunction *self, PyObjec
 #if PG_DEBUG > 0
 	g_printerr("calling error\n");
 #endif
+        if (ret[1].type == GIMP_PDB_STRING)
+	  PyErr_SetString(PyExc_RuntimeError, ret[1].data.d_string);
+        else
+          PyErr_SetString(PyExc_RuntimeError, "calling error");
 	gimp_destroy_params(ret, nret);
-	PyErr_SetString(PyExc_TypeError, "invalid arguments");
 	return NULL;
 	break;
 
