diff --git a/pd/src/m_class.c b/pd/src/m_class.c
index a398ffb15351846dfaa22cc209dd452928a04c4a..c582318b9cdde1a9d2e290df08eb45c59bbacd5d 100644
--- a/pd/src/m_class.c
+++ b/pd/src/m_class.c
@@ -99,18 +99,29 @@ char *type_hint(t_symbol *s, int argc, t_atom *argv, int dostof)
     {
         if (symbol_can_float(atom_getsymbolarg(0, argc, argv), &f))
         {
-            sprintf(hint, " (Note: this symbol message has a floatlike payload "
-                "which cannot be saved properly. Did you mean 'float %s'?)",
-                argv->a_w.w_symbol->s_name);
+            if (s == &s_symbol)
+                sprintf(hint, " (Warning: symbol message with numeric payload "
+                "detected. This data cannot be saved properly in a patch.");
+            else
+                sprintf(hint, " (Note: '%s' is actually a symbol atom, not "
+                    "a float)",
+                    argv->a_w.w_symbol->s_name);
             return hint;
         }
         else if (f == -1 || f == 1)
         {
                 /* For values which would overflow, give a hint but don't
                    suggest float type */
-            sprintf(hint, " (Note: this symbol message has an %s floatlike "
-                "payload which cannot be saved properly.",
-                f == 1 ? "overflowing" : "underflowing");
+            if (s == &s_symbol)
+                sprintf(hint, " (Note: this symbol message has an %s floatlike "
+                    "payload which cannot be saved properly.",
+                    f == 1 ? "overflowing" : "underflowing");
+            else
+                sprintf(hint, " (Note: '%s' is actually a symbol atom. If you "
+                    "save it Pd will parse it as a float and cause an %s "
+                    "error.",
+                    argv->a_w.w_symbol->s_name,
+                    f == 1 ? "overflow" : "underflow");
             return hint;
         }
     }
@@ -129,13 +140,33 @@ char *type_hint(t_symbol *s, int argc, t_atom *argv, int dostof)
         {
                 /* For values which would overflow, give a hint but don't
                    suggest float type */
-            sprintf(hint, " (Note: this symbol atom has an %s floatlike "
+            sprintf(hint, " (Note: the symbol atom '%s' has an %s floatlike "
                 "payload which cannot be saved properly.",
+                s->s_name,
                 f == 1 ? "overflowing" : "underflowing");
             return hint;
         }
     }
 
+        /* Now that we've checked for symbols that could be floats, let's
+           catch the generic case where a user entered a symbol payload for a
+           "float" message. This can be typed into a messsage box, for
+           example. We also check for empty symbol payload here, and other
+           odd atom types */
+    if (s && s == &s_float && argc && argv->a_type != A_FLOAT)
+    {
+        if (argv->a_type == A_SYMBOL && argv->a_w.w_symbol == &s_)
+            sprintf(hint, " (Expected a float argument but got empty symbol)");
+        else if (argv->a_type == A_SYMBOL)
+            sprintf(hint, " (Expected a float argument but got '%s')",
+                argv->a_w.w_symbol->s_name);
+        else if (argv->a_type == A_POINTER)
+            sprintf(hint, " (Expected a float argument but got a gpointer)");
+        else
+            sprintf(hint, " (Note: got an argument that's not a float)");
+        return hint;
+    }
+
     hint[0] = '\0';
     return hint;
 }
@@ -150,7 +181,7 @@ static void pd_defaultanything(t_pd *x, t_symbol *s, int argc, t_atom *argv)
 static void pd_defaultbang(t_pd *x)
 {
     if (*(*x)->c_listmethod != pd_defaultlist)
-        (*(*x)->c_listmethod)(x, 0, 0, 0);
+        (*(*x)->c_listmethod)(x, &s_bang, 0, 0);
     else (*(*x)->c_anymethod)(x, &s_bang, 0, 0);
 }
 
@@ -165,7 +196,7 @@ static void pd_defaultpointer(t_pd *x, t_gpointer *gp)
     {
         t_atom at;
         SETPOINTER(&at, gp);
-        (*(*x)->c_listmethod)(x, 0, 1, &at);
+        (*(*x)->c_listmethod)(x, &s_pointer, 1, &at);
     }
     else
     {
@@ -181,7 +212,7 @@ static void pd_defaultfloat(t_pd *x, t_float f)
     {
         t_atom at;
         SETFLOAT(&at, f);
-        (*(*x)->c_listmethod)(x, 0, 1, &at);
+        (*(*x)->c_listmethod)(x, &s_float, 1, &at);
     }
     else
     {
@@ -197,7 +228,7 @@ static void pd_defaultsymbol(t_pd *x, t_symbol *s)
     {
         t_atom at;
         SETSYMBOL(&at, s);
-        (*(*x)->c_listmethod)(x, 0, 1, &at);
+        (*(*x)->c_listmethod)(x, &s_symbol, 1, &at);
     }
     else
     {
@@ -1091,8 +1122,10 @@ badarg:
        message that contains it (so it can be selected when 'Find
        Error' is used). */
     x = pd_mess_from_responder(x);
-    pd_error(x, "Bad arguments for message '%s' to object '%s'",
-        s->s_name, c->c_name->s_name);
+    pd_error(x, "Bad arguments for message '%s' to object '%s'%s",
+        s->s_name,
+        c->c_name->s_name,
+        type_hint(s, argc, argv, 1));
 lastmess:
     last_typedmess = s;    
     last_typedmess_pd = x;
@@ -1168,7 +1201,10 @@ t_gotfn getfn(t_pd *x, t_symbol *s)
 
     for (i = c->c_nmethod, m = c->c_methods; i--; m++)
         if (m->me_name == s) return(m->me_fun);
-    pd_error(x, "%s: no method for message '%s'", c->c_name->s_name, s->s_name);
+    pd_error(x, "%s: no method for message '%s'%s",
+            c->c_name->s_name,
+            s->s_name,
+            type_hint(s, 0, 0, 1));
     return((t_gotfn)nullfn);
 }
 
diff --git a/pd/src/x_interface.c b/pd/src/x_interface.c
index bfb69df38ccd1a179c50b50b510dad75cbb302ae..79c204023160b6b36e782d9fd6690fb9f122bb39 100644
--- a/pd/src/x_interface.c
+++ b/pd/src/x_interface.c
@@ -325,6 +325,12 @@ typedef struct _objectinfo {
     t_canvas *x_canvas;
 } t_objectinfo;
 
+static t_class *debuginfo_class;
+
+typedef struct _debuginfo {
+    t_object x_obj;
+} t_debuginfo;
+
 /* used by all the *info objects */
 
 static int info_to_console = 0;
@@ -1623,12 +1629,43 @@ void objectinfo_setup(void)
     post("stable objectinfo methods: class");
 }
 
+void debuginfo_print(t_debuginfo *x)
+{
+    info_print((t_text *)x);
+}
+
+    /* replace incoming message's selector with zero and output it */
+void debuginfo_nullselector(t_debuginfo *x, t_symbol *s, int argc,
+    t_atom *argv)
+{
+    info_out((t_text *)x, 0, argc, argv);
+}
+
+void *debuginfo_new(void)
+{
+    t_debuginfo *x = (t_debuginfo *)pd_new(debuginfo_class);
+    outlet_new(&x->x_obj, &s_anything);
+    return (void *)x;
+}
+
+void debuginfo_setup(void)
+{
+    debuginfo_class = class_new(gensym("debuginfo"),
+        (t_newmethod)debuginfo_new, 0, sizeof(t_debuginfo),
+        CLASS_DEFAULT, 0);
+    class_addmethod(debuginfo_class, (t_method)debuginfo_nullselector,
+        gensym("null-selector"), A_GIMME, 0);
+    class_addmethod(debuginfo_class, (t_method)debuginfo_print,
+        gensym("print"), A_GIMME, 0);
+}
+
 void x_interface_setup(void)
 {
-    print_setup();
-    unpost_setup();
     canvasinfo_setup();
-    pdinfo_setup();
     classinfo_setup();
+    debuginfo_setup();
     objectinfo_setup();
+    pdinfo_setup();
+    print_setup();
+    unpost_setup();
 }