Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug: ReadString() too long: please show the variable that caused it

Discussion in 'Multiplayer' started by mischa2k, Apr 4, 2016.

  1. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    The ReadString too long bug still happens in 5.3.4, even when using the Reliable Fragmented channel and testing on a local machine:
    Code (CSharp):
    1. IndexOutOfRangeException: ReadString() too long: 44564
    2. UnityEngine.Networking.NetworkReader.ReadString () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:294)
    3. Entity.OnDeserialize (UnityEngine.Networking.NetworkReader reader, Boolean initialState)
    4. Building.OnDeserialize (UnityEngine.Networking.NetworkReader reader, Boolean initialState)
    5. UnityEngine.Networking.NetworkIdentity.OnUpdateVars (UnityEngine.Networking.NetworkReader reader, Boolean initialState) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:753)
    6. UnityEngine.Networking.ClientScene.ApplySpawnPayload (UnityEngine.Networking.NetworkIdentity uv, Vector3 position, System.Byte[] payload, NetworkInstanceId netId, UnityEngine.GameObject newGameObject) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:478)
    7. UnityEngine.Networking.ClientScene.OnObjectSpawnScene (UnityEngine.Networking.NetworkMessage netMsg) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:589)
    8. UnityEngine.Networking.NetworkConnection.HandleReader (UnityEngine.Networking.NetworkReader reader, Int32 receivedSize, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:430)
    9. UnityEngine.Networking.NetworkConnection.HandleBytes (System.Byte[] buffer, Int32 receivedSize, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:386)
    10. UnityEngine.Networking.NetworkConnection.TransportRecieve (System.Byte[] bytes, Int32 numBytes, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:536)
    11. UnityEngine.Networking.NetworkClient.Update () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:648)
    12. UnityEngine.Networking.NetworkClient.UpdateClients () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:861)
    13. UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1059)
    14.  
    My Entity class doesn't have anything too long in it. I see this bug about once a day, it occurs again sometimes after changing some code, then it disappears after changing code, then it appears again after changing other code.

    I encountered it last October already, but then at some point the bug didn't happen anymore, but it's back now.

    Since this bug pops up on the UNET forum every now and then, it would be awesome if someone can take a look at it and improve the error message to at least tell us where it happens, or fix the bug.
    I suggest wrapping the automated serialization part in a try/catch block and then throwing a exception with the exact name of the variable that failed to deserialize. Perhaps even use one try/catch block for each variable if you have to. But currently the error message is useless and leave us like 'well, let's refactor the code a bit more until it works again and then randomly'.

    I can send my project files to anyone from the Unity team, but can't upload them publicly.

    Greetings
     
    Last edited: Apr 4, 2016
  2. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Update: I am able to track it down to one GameObject that causes it. I have several 'entities' in the Scene, for example Monsters, Players, Npcs etc. and one of them causes the error, even though it has no custom strings that are synchronized, only what is in the base Entity class - which works fine for all the other entities.
     
  3. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Update: now I have a new error caused by another Entity:
    Code (CSharp):
    1. IndexOutOfRangeException: NetworkReader:ReadByte out of range:NetBuf sz:4 pos:4
    2. UnityEngine.Networking.NetBuffer.ReadByte () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkBuffer.cs:35)
    3. UnityEngine.Networking.NetworkReader.ReadUInt32 () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:201)
    4. UnityEngine.Networking.NetworkReader.ReadSingle () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:270)
    5. UnityEngine.Networking.NetworkReader.ReadVector3 () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:346)
    6. NetworkNavMeshAgent.OnDeserialize (UnityEngine.Networking.NetworkReader reader, Boolean initialState) (at Assets/uMOBA/Scripts/NetworkNavMeshAgent.cs:49)
    7. UnityEngine.Networking.NetworkIdentity.OnUpdateVars (UnityEngine.Networking.NetworkReader reader, Boolean initialState) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:753)
    8. UnityEngine.Networking.ClientScene.ApplySpawnPayload (UnityEngine.Networking.NetworkIdentity uv, Vector3 position, System.Byte[] payload, NetworkInstanceId netId, UnityEngine.GameObject newGameObject) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:478)
    9. UnityEngine.Networking.ClientScene.OnObjectSpawnScene (UnityEngine.Networking.NetworkMessage netMsg) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:589)
    10. UnityEngine.Networking.NetworkConnection.HandleReader (UnityEngine.Networking.NetworkReader reader, Int32 receivedSize, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:430)
    11. UnityEngine.Networking.NetworkConnection.HandleBytes (System.Byte[] buffer, Int32 receivedSize, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:386)
    12. UnityEngine.Networking.NetworkConnection.TransportRecieve (System.Byte[] bytes, Int32 numBytes, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:536)
    13. UnityEngine.Networking.NetworkClient.Update () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:648)
    14. UnityEngine.Networking.NetworkClient.UpdateClients () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:861)
    15. UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1059)
    16.  
    Here is the line from my Script that is mentioned in the error message above:
    Code (CSharp):
    1.  
    2. var pos = reader.ReadVector3();
    3.  

    So since it once happens in my custom serialization and once in UNET's automated serialization, the error is very likely somewhere in the SpawnPayload function...

    Edit: it also crashes the Unity Editor and build occasionally!
    Edit2: using the 'All Cost Delivery' channel fixes the ReadByte out of range bug. The first bug still persists.
     
    Last edited: Apr 4, 2016
  4. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Update: I removed the only SyncVar string from my Entity class. Now the first error doesn't happen anymore because ReadString isn't called anymore. It was replaced by the second error again though:
    Code (CSharp):
    1. IndexOutOfRangeException: NetworkReader:ReadByte out of range:NetBuf sz:4 pos:4
    2. UnityEngine.Networking.NetBuffer.ReadByte () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkBuffer.cs:35)
    3. UnityEngine.Networking.NetworkReader.ReadUInt32 () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:201)
    4. UnityEngine.Networking.NetworkReader.ReadSingle () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:270)
    5. UnityEngine.Networking.NetworkReader.ReadVector3 () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkReader.cs:346)
    6. NetworkNavMeshAgent.OnDeserialize (UnityEngine.Networking.NetworkReader reader, Boolean initialState) (at Assets/uMOBA/Scripts/NetworkNavMeshAgent.cs:49)
    7. UnityEngine.Networking.NetworkIdentity.OnUpdateVars (UnityEngine.Networking.NetworkReader reader, Boolean initialState) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:753)
    8. UnityEngine.Networking.ClientScene.ApplySpawnPayload (UnityEngine.Networking.NetworkIdentity uv, Vector3 position, System.Byte[] payload, NetworkInstanceId netId, UnityEngine.GameObject newGameObject) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:478)
    9. UnityEngine.Networking.ClientScene.OnObjectSpawnScene (UnityEngine.Networking.NetworkMessage netMsg) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:589)
    10. UnityEngine.Networking.NetworkConnection.HandleReader (UnityEngine.Networking.NetworkReader reader, Int32 receivedSize, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:430)
    11. UnityEngine.Networking.NetworkConnection.HandleBytes (System.Byte[] buffer, Int32 receivedSize, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:386)
    12. UnityEngine.Networking.NetworkConnection.TransportRecieve (System.Byte[] bytes, Int32 numBytes, Int32 channelId) (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:536)
    13. UnityEngine.Networking.NetworkClient.Update () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:648)
    14. UnityEngine.Networking.NetworkClient.UpdateClients () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:861)
    15. UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at /home/builduser/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1059)
    16.  
     
    Last edited: Apr 6, 2016
  5. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
    Okay so after 8 months I finally found out why it happens and reported a demo as bug #786248.

    Errors in OnSerialize/OnDeserialize are not shown in the console because they happen in UNET somewhere. As result, UNET's packet gets messed up and sent to the client (or skipped?) and the client then tries to parse a messed up (or skipped) packet. Hence random ReadByte out of range / ReadString too long errors.

    I hope someone from the UNET team ( @JeremyUnity ?) looks at it (or confirms it for now), since this seems to be the worst UNET bug around, affected several people, happens randomly and is almost impossible to understand/work around from the error message.

    Edit: it was confirmed by the Q&A team!

    Cheers
     
    Last edited: Apr 7, 2016
    moco2k and Nightology like this.
  6. desertkun

    desertkun

    Joined:
    Jan 13, 2016
    Posts:
    8
    Thank you for the effort, I've been hunting this bug for a while. Voted for the bug.
     
  7. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
  8. bullardo

    bullardo

    Joined:
    Jan 5, 2013
    Posts:
    46
    I also just went and voted on this issue.
     
  9. Chequered

    Chequered

    Joined:
    Feb 3, 2014
    Posts:
    2
    If anyone is still having this issue, I think I found the cause of the error.

    It's probably because you are calling ReadMessage a second time. this is why the position is already at the range of the byte size in the error. You can overwrite the deserializer and put reader.SeekZero() at the start of your deserializer to make sure it always starts at zero. Hope this helps someout out because it took me 2 days to find out what was causing this.
     
  10. MechEthan

    MechEthan

    Joined:
    Mar 23, 2016
    Posts:
    166
    TLDR: Make sure you're running the same build on all clients/hosts. You may have changed what data is getting passed around!

    I ran into this exact style of message because I was connecting two mismatched versions of my app.

    I'd added a field to a struct that was being synchronized, but only updated one of my two test devices with a build containing the latest code changes to the struct. So, of course it can't deserialize into a different data structure... oops!
     
  11. mischa2k

    mischa2k

    Joined:
    Sep 4, 2015
    Posts:
    4,347
  12. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    I don't know if those are related, but I'm getting similar error with Unity 2017.1b10 at 100% rate. I'm using double project setup, but I've triple checked - files are identical in both of them.
    Does anyone knows why it could be happening with this struct? Initialize is called in OnServerStart();

    Code (CSharp):
    1. using UnityEngine.Networking;
    2.     public class PlayerDataSyncList : SyncListStruct<PlayerData> {
    3.         public void Initialize() {
    4.             PlayerData nullPlayer = new PlayerData(NetworkInstanceId.Invalid);
    5.             Add(nullPlayer);
    6.         }
    7.  
    8.         /// <summary>
    9.         /// Removes player with playerId from list
    10.         /// </summary>
    11.         public void RemoveById(NetworkInstanceId playerId) {
    12.             for (int i = 0; i < Count; i++) {
    13.                 if (this[i].Id == playerId) {
    14.                     RemoveAt(i);
    15.                 }
    16.             }
    17.         }
    18.     }
    19.  
    20.     [System.Serializable]
    21.     public struct PlayerData {
    22.         public NetworkInstanceId Id;
    23.         public string Username;
    24.         public string VisibleUsername;
    25.  
    26.         public PlayerTeam PlayerTeam;
    27.         public int PeerId;
    28.  
    29.         public PlayerData(NetworkInstanceId id,
    30.                           int peerId = -1,
    31.                           string username = null,
    32.                           string visibleUsername = null,
    33.                           PlayerTeam playerTeam = PlayerTeam.Undefined) {
    34.             Id = id;
    35.             Username = username;
    36.             VisibleUsername = visibleUsername;
    37.             PeerId = peerId;
    38.             PlayerTeam = playerTeam;
    39.         }
    40.     }
    41.  
    42.     public static class PlayerDataExt {
    43.         public const string NonamePrefix = "Noname player";
    44.     }
    45.  
    46.     [System.Serializable]
    47.     public enum PlayerTeam {
    48.         FFA,
    49.         TVT1,
    50.         TVT2,
    51.         Undefined
    52.     }
    53.  
    I don't think it should be beyond that range in the first case, since I'm not sending too much data - strings are less than 10 chars long.

    Edit: This only fails when there's more than one PlayerData exists in the list. It works fine when there's only one player in the list.
     
    Last edited: Jun 27, 2017