Yowsup: AttributeError: 'NoneType' object has no attribute 'getChild'

Created on 18 Apr 2016  Â·  14Comments  Â·  Source: tgalal/yowsup

Hi, I'm trying to use Whatsapp in my Raspberry Pi 3. The problem is when I try to send a message from my Raspberry Pi to my phone. That's the error:

pi@raspberrypi:~/yowsup $ python yowsup-cli demos --config yowsup-cli.config --send XXXXXXX "hola"
yowsup-cli v2.0.15
yowsup v2.4.102

Copyright (c) 2012-2016 Tarek Galal
http://www.openwhatsapp.org

This software is provided free of charge. Copying and redistribution is
encouraged.

If you appreciate this software and you would like to support future
development please consider donating:
http://openwhatsapp.org/yowsup/donate

Traceback (most recent call last):
File "yowsup-cli", line 369, in
if not parser.process():
File "yowsup-cli", line 273, in process
self.startSendClient()
File "yowsup-cli", line 325, in startSendClient
stack.start()
File "/home/pi/yowsup/yowsup/demos/sendclient/stack.py", line 31, in start
self.stack.loop()
File "/home/pi/yowsup/yowsup/stacks/yowstack.py", line 195, in loop
asyncore.loop(_args, *_kwargs)
File "/usr/lib/python2.7/asyncore.py", line 216, in loop
poll_fun(timeout, map)
File "/usr/lib/python2.7/asyncore.py", line 156, in poll
read(obj)
File "/usr/lib/python2.7/asyncore.py", line 87, in read
obj.handle_error()
File "/usr/lib/python2.7/asyncore.py", line 83, in read
obj.handle_read_event()
File "/usr/lib/python2.7/asyncore.py", line 449, in handle_read_event
self.handle_read()
File "/home/pi/yowsup/yowsup/layers/network/layer.py", line 88, in handle_read
self.receive(data)
File "/home/pi/yowsup/yowsup/layers/network/layer.py", line 96, in receive
self.toUpper(data)
File "/home/pi/yowsup/yowsup/layers/init.py", line 75, in toUpper
self.upper.receive(data)
File "/home/pi/yowsup/yowsup/layers/stanzaregulator/layer.py", line 29, in receive
self.processReceived()
File "/home/pi/yowsup/yowsup/layers/stanzaregulator/layer.py", line 49, in processReceived
self.toUpper(oneMessageData)
File "/home/pi/yowsup/yowsup/layers/__init
.py", line 75, in toUpper
self.upper.receive(data)
File "/home/pi/yowsup/yowsup/layers/auth/layer_crypt.py", line 65, in receive
self.toUpper(payload)
File "/home/pi/yowsup/yowsup/layers/__init
.py", line 75, in toUpper
self.upper.receive(data)
File "/home/pi/yowsup/yowsup/layers/coder/layer.py", line 35, in receive
self.toUpper(node)
File "/home/pi/yowsup/yowsup/layers/__init
.py", line 75, in toUpper
self.upper.receive(data)
File "/home/pi/yowsup/yowsup/layers/logger/layer.py", line 14, in receive
self.toUpper(data)
File "/home/pi/yowsup/yowsup/layers/__init
.py", line 75, in toUpper
self.upper.receive(data)
File "/home/pi/yowsup/yowsup/layers/axolotl/layer.py", line 122, in receive
if not self.processIqRegistry(protocolTreeNode):
File "/home/pi/yowsup/yowsup/layers/__init
.py", line 155, in processIqRegistry
successClbk(protocolTreeNode, originalIq)
File "/home/pi/yowsup/yowsup/layers/axolotl/layer.py", line 182, in
self._sendIq(entity, lambda a, b: self.onGetKeysResult(a, b, self.processPendingMessages), self.onGetKeysError)
File "/home/pi/yowsup/yowsup/layers/axolotl/layer.py", line 346, in onGetKeysResult
entity = ResultGetKeysIqProtocolEntity.fromProtocolTreeNode(resultNode)
File "/home/pi/yowsup/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py", line 88, in fromProtocolTreeNode
preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
AttributeError: ‘NoneType’ object has no attribute ‘getChild’

I didn't find this error anywhere. Could any help me, please??

Most helpful comment

@SpEcHiDe I used this workaround, but it is not tested very well and can have negative side-effects. That is why I did not create a pull request.

 diff --git a/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py b/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 index 79b34cb..4f6086a 100644
 --- a/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 +++ b/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 @@ -7,6 +7,7 @@ from axolotl.ecc.curve import Curve
  from axolotl.ecc.djbec import DjbECPublicKey
  import binascii
  import sys
 +import logging
  class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
      """
      <iq type="result" from="s.whatsapp.net" id="3">
 @@ -81,13 +82,20 @@ class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
          userNodes = node.getChild("list").getAllChildren()
          for userNode in userNodes:
              preKeyNode = userNode.getChild("key")
 +            if (preKeyNode is None):
 +                logger = logging.getLogger(__name__)
 +                logger.warning("Failed to receive preKeyNode for %s"%(userNode.getAttributeValue("jid") if "jid" in userNode.attributes else "unknown"))
 +                # it seems, simply using None for IDs breaks sending, but at last allows receiving
 +                preKeyId = None
 +                preKeyPublic = None
 +            else:
 +                preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
 +                preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
 +
              signedPreKeyNode = userNode.getChild("skey")
              registrationId = ResultGetKeysIqProtocolEntity._bytesToInt(userNode.getChild("registration").getData())
              identityKey = IdentityKey(DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(userNode.getChild("identity").getData())))

 -            preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
 -            preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
 -
              signedPreKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(signedPreKeyNode.getChild("id").getData())
              signedPreKeySig = ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("signature").getData())
              signedPreKeyPub = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("value").getData()))

All 14 comments

You are sending a message to someone which hasn't wa or you put incorrectly the jid. Sync contact if you get the number out, you found the error.

I have the same issue.

This issue does NOT occur if i do /send [number] [message] in the command line client.

                                                                                  Make the first login with cli app to generate keys:yowsup‎-cli demos -y -d -c configfileAnd then /L

EDIT: Issue resolved, at least for me.

Hi, I have the same problem to send message to a list of phones:

File "applications/whatsapp/modules/sendclient/stack.py", line 38, in start
self.stack.loop()
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/stacks/yowstack.py", line 196, in loop
asyncore.loop(_args, *_kwargs)
File "/home/diego/anaconda2/lib/python2.7/asyncore.py", line 216, in loop
poll_fun(timeout, map)
File "/home/diego/anaconda2/lib/python2.7/asyncore.py", line 156, in poll
read(obj)
File "/home/diego/anaconda2/lib/python2.7/asyncore.py", line 87, in read
obj.handle_error()
File "/home/diego/anaconda2/lib/python2.7/asyncore.py", line 83, in read
obj.handle_read_event()
File "/home/diego/anaconda2/lib/python2.7/asyncore.py", line 449, in handle_read_event
self.handle_read()
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 102, in handle_read
self.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/network/layer.py", line 110, in receive
self.toUpper(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 76, in toUpper
self.upper.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 29, in receive
self.processReceived()
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/stanzaregulator/layer.py", line 49, in processReceived
self.toUpper(oneMessageData)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init
.py", line 76, in toUpper
self.upper.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/auth/layer_crypt.py", line 65, in receive
self.toUpper(payload)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init
.py", line 76, in toUpper
self.upper.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/coder/layer.py", line 35, in receive
self.toUpper(node)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init
.py", line 76, in toUpper
self.upper.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/logger/layer.py", line 14, in receive
self.toUpper(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init
.py", line 76, in toUpper
self.upper.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_control.py", line 44, in receive
self.toUpper(protocolTreeNode)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init
.py", line 76, in toUpper
self.upper.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/__init
.py", line 189, in receive
s.receive(data)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_send.py", line 64, in receive
if not self.processIqRegistry(protocolTreeNode):
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/init.py", line 156, in processIqRegistry
successClbk(protocolTreeNode, originalIq)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/layer_base.py", line 51, in onSuccess
entity = ResultGetKeysIqProtocolEntity.fromProtocolTreeNode(resultNode)
File "/home/diego/anaconda2/lib/python2.7/site-packages/yowsup2-2.5.0-py2.7.egg/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py", line 88, in fromProtocolTreeNode
preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
AttributeError: 'NoneType' object has no attribute 'getChild'

I tried what @jlguardi said but unsuccessful.
can anyone help me?

@DiegoVallely I've experienced this kind of exception if I send a message to somebody which isn't registered in whatsapp or his jid contains an extra number (i.e: phone 5435xxx has whatsapp jid 54935xxx@wha...)

@jlguardi how can I know if a number has an extra number or isn't registered in whatsapp before I send message?

Sync contact info with GetSyncIqProtocolEntity

EDIT: I am stupid. I acutally used a completely wrong phone number for the message destination. The "/contatcs sync" output is terribly misleading ("Invalid Numbers" is empty). Nevertheless, I first experienced this problem upon receiving. Maybe this can happen if you receive a message from someone who managed to have their account deleted?

I face the same problem. It seems to occur as soon as I send a message to a contact I don't have the encryption keys for. As you can see in the debug output, the server actually does not send the "key" section. As a result, userNode.getChild("key") cannot possibly return a valid node. Here is the full log:

$ python yowsup-cli demos -c ~/.yowsuup/config -y -d
yowsup-cli  v2.0.15
yowsup      v2.5.0

Copyright (c) 2012-2016 Tarek Galal
http://www.openwhatsapp.org

This software is provided free of charge. Copying and redistribution is
encouraged.

If you appreciate this software and you would like to support future
development please consider donating:
http://openwhatsapp.org/yowsup/donate


DEBUG:yowsup.env.env:Env not set, setting it to s40
DEBUG:yowsup.env.env:Current env changed to s40 
DEBUG:yowsup.stacks.yowstack:Initializing stack
DEBUG:yowsup.stacks.yowstack:Constructed Network Layer
DEBUG:yowsup.stacks.yowstack:Constructed Stanza Regulator Layer
DEBUG:yowsup.stacks.yowstack:Constructed Crypt Layer
DEBUG:yowsup.stacks.yowstack:Constructed Coder Layer
DEBUG:yowsup.stacks.yowstack:Constructed Logger Layer
DEBUG:yowsup.stacks.yowstack:Constructed <yowsup.layers.axolotl.layer_control.AxolotlControlLayer object at 0x7fbf1a0214d0>
DEBUG:yowsup.stacks.yowstack:Constructed Axolotl Layer - <yowsup.layers.axolotl.layer_receive.AxolotlReceivelayer object at 0x7fbf1a00ebd0>
DEBUG:yowsup.stacks.yowstack:Constructed Authentication Layer - Messages Layer - Receipt Layer - Ack Layer - Presence Layer - Ib Layer - Iq Layer - notification Ib Layer - Iq Layer - Chatstate Layer - call Layer - Groups Iq Layer - Media Layer - Privacy Layer - Profiles Layer
DEBUG:yowsup.stacks.yowstack:Constructed CLI Interface Layer
Yowsup Cli client
==================
Type /help for available commands

[offline]:/L
DEBUG:yowsup.layers.network.layer:Connecting to e5.whatsapp.net:443
Auth: Logged in!

[connected]:/contacts sync REDACTED491
DEBUG:yowsup.layers.logger.layer:tx:
<iq xmlns="urn:xmpp:whatsapp:sync" type="get" id="1">
<sync index="0" last="true" mode="full" context="interactive" sid="131282676660000000">
<user>
REDACTED491
</user>
</sync>
</iq>

DEBUG:yowsup.layers.logger.layer:rx:
<iq type="result" from="[email protected]" id="1">
<sync index="0" wait="564036" last="true" version="1483790355962371" sid="131282676660000000">
<out>
<user jid="[email protected]">
REDACTED491
</user>
</out>
</sync>
</iq>

Iq:
ID: 1
Type: result
from: [email protected]
Wait: 564036
Version: 1483790355962371
In Numbers: 
Out Numbers: REDACTED491
Invalid Numbers: 

[connected]:/message send REDACTED491 test
DEBUG:yowsup.layers.logger.layer:tx:
<iq to="s.whatsapp.net" xmlns="encrypt" type="get" id="3">
<key>
<user jid="[email protected]">
</user>
</key>
</iq>

DEBUG:yowsup.layers.protocol_iq.layer:ping queue size: 1
DEBUG:yowsup.layers.logger.layer:tx:
<iq xmlns="w:p" type="get" id="4">
</iq>

DEBUG:yowsup.layers.logger.layer:rx:
<iq type="result" from="[email protected]" id="4" t="1483790496">
</iq>

Iq:
ID: 4
Type: result
from: [email protected]

DEBUG:yowsup.layers.logger.layer:rx:
<iq type="result" from="s.whatsapp.net" id="3">
<list>
<user jid="[email protected]">
<registration>
REDACTED
</registration>
<type>
HEX:05
</type>
<identity>
REDACTED
</identity>
<skey>
<id>
REDACTED
</id>
<value>
REDACTED
</value>
<signature>
REDACTED
</signature>
</skey>
</user>
</list>
</iq>

Traceback (most recent call last):
  STRIPPED BORING PARTS
  File "yowsup/layers/axolotl/layer_send.py", line 64, in receive
    if not self.processIqRegistry(protocolTreeNode):
  File "yowsup/layers/__init__.py", line 156, in processIqRegistry
    successClbk(protocolTreeNode, originalIq)
  File "yowsup/layers/axolotl/layer_base.py", line 51, in onSuccess
    entity = ResultGetKeysIqProtocolEntity.fromProtocolTreeNode(resultNode)
  File "yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py", line 88, in fromProtocolTreeNode
preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
AttributeError: ‘NoneType’ object has no attribute ‘getChild’

@hoehermann your edit is right. I've managed exception when no key is returned and checked for existing account.

Was someone able to fix this? Especially for the extra number? We tested sending messages to foreign numbers like dubai (+971, extra country code number and also longer numbers dan in the netherlands +31) and it returns AttributeError: ‘NoneType’ object has no attribute ‘getChild’ and crashes the application.

@jlguardi Can you please tell me the fix?

@SpEcHiDe I used this workaround, but it is not tested very well and can have negative side-effects. That is why I did not create a pull request.

 diff --git a/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py b/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 index 79b34cb..4f6086a 100644
 --- a/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 +++ b/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 @@ -7,6 +7,7 @@ from axolotl.ecc.curve import Curve
  from axolotl.ecc.djbec import DjbECPublicKey
  import binascii
  import sys
 +import logging
  class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
      """
      <iq type="result" from="s.whatsapp.net" id="3">
 @@ -81,13 +82,20 @@ class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
          userNodes = node.getChild("list").getAllChildren()
          for userNode in userNodes:
              preKeyNode = userNode.getChild("key")
 +            if (preKeyNode is None):
 +                logger = logging.getLogger(__name__)
 +                logger.warning("Failed to receive preKeyNode for %s"%(userNode.getAttributeValue("jid") if "jid" in userNode.attributes else "unknown"))
 +                # it seems, simply using None for IDs breaks sending, but at last allows receiving
 +                preKeyId = None
 +                preKeyPublic = None
 +            else:
 +                preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
 +                preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
 +
              signedPreKeyNode = userNode.getChild("skey")
              registrationId = ResultGetKeysIqProtocolEntity._bytesToInt(userNode.getChild("registration").getData())
              identityKey = IdentityKey(DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(userNode.getChild("identity").getData())))

 -            preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
 -            preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
 -
              signedPreKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(signedPreKeyNode.getChild("id").getData())
              signedPreKeySig = ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("signature").getData())
              signedPreKeyPub = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("value").getData()))

@SpEcHiDe I used this workaround, but it is not tested very well and can have negative side-effects. That is why I did not create a pull request.

 diff --git a/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py b/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 index 79b34cb..4f6086a 100644
 --- a/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 +++ b/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py
 @@ -7,6 +7,7 @@ from axolotl.ecc.curve import Curve
  from axolotl.ecc.djbec import DjbECPublicKey
  import binascii
  import sys
 +import logging
  class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
      """
      <iq type="result" from="s.whatsapp.net" id="3">
 @@ -81,13 +82,20 @@ class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
          userNodes = node.getChild("list").getAllChildren()
          for userNode in userNodes:
              preKeyNode = userNode.getChild("key")
 +            if (preKeyNode is None):
 +                logger = logging.getLogger(__name__)
 +                logger.warning("Failed to receive preKeyNode for %s"%(userNode.getAttributeValue("jid") if "jid" in userNode.attributes else "unknown"))
 +                # it seems, simply using None for IDs breaks sending, but at last allows receiving
 +                preKeyId = None
 +                preKeyPublic = None
 +            else:
 +                preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
 +                preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
 +
              signedPreKeyNode = userNode.getChild("skey")
              registrationId = ResultGetKeysIqProtocolEntity._bytesToInt(userNode.getChild("registration").getData())
              identityKey = IdentityKey(DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(userNode.getChild("identity").getData())))

 -            preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
 -            preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
 -
              signedPreKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(signedPreKeyNode.getChild("id").getData())
              signedPreKeySig = ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("signature").getData())
              signedPreKeyPub = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("value").getData()))

Oh man, this works for me! You save my life :D rsrs Thanks

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexvong1995 picture alexvong1995  Â·  4Comments

EliasinnKamachoo picture EliasinnKamachoo  Â·  3Comments

dickbutt2 picture dickbutt2  Â·  3Comments

Realitaetsverlust picture Realitaetsverlust  Â·  4Comments

thatskriptkid picture thatskriptkid  Â·  3Comments