-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unhandled Exception: RangeError: Not enough bytes available. #424
Comments
Could you reproduce the issue? |
this issue is solved when i delete local data. |
Again Facing this issue in flutter web. Can't able to resolve it.
|
Did the issue happened after changing model structure or randomly? |
nope, it is working fine when i start debugging. after i restart 2-3 time. this error happens |
First application start is ok, but second and all the next causes crash |
Could you share code with us to identify cause? |
when i clear all cache & storage and run builder again this issue is resolved |
I call Method invokation |
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: RangeError: Not enough bytes available. any find the problem |
For several days I suffered with the same problem and could not understand why it appears. Changed package versions and much more. Everything turned out to be trite. This fixed my problem. |
I figured it (atleast in my case). This was my code: SessionTokenInfo read(BinaryReader reader) {
print("read ${reader.readString()}");
return SessionTokenInfo.fromJson(jsonDecode(reader.readString()));
} I was reading from the same BinaryReader twice. I assume there's a finite buffer that gets cleared as you read. Calling read twice (apparently) was the problem. I hope this helps someone else. |
Instead of reading twice you can store value in variable then use it twice. SessionTokenInfo read(BinaryReader reader) {
final str = reader.readString();
print('read $str');
return SessionTokenInfo.fromJson(jsonDecode(str));
} |
i occur the same problem,i did know what went wrong? |
@HumesFork please proof-read your comment. The previous comment explain the issue clearly. @leisim Maybe improve the error message? Seems a decent number of devs all find it unclear. |
@cosmotek that's not so easy because there are a lot of reasons why this error may happen. Do you have a suggestion? |
facing this issue using firestore. when i store firestore data locally and then restart my app. i get the following error - [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: RangeError: Not enough bytes available. |
I had this exact same issue, in my case I created an adapter for the flutter math Point class which I used inside one of my business logic classes. The adapter I first created was like this: class PointAdapter extends TypeAdapter<Point> {
@override
final typeId = HiveUtils.POINT_TYPE_ID;
@override
Point read(BinaryReader reader) => Point(reader.read(0), reader.read(1));
@override
void write(BinaryWriter writer, Point obj) {
writer
..writeByte(2)
..writeByte(0)
..write(obj.x)
..writeByte(1)
..write(obj.y);
}
} But the Point class is a flutter framework class and doesn't have @HiveField set for 'x' and 'y'... so the first time the app runs everything gets stored fine but after a hot restart the reader throws the RangeError exception. Then I updated the adapter to this: class PointAdapter extends TypeAdapter<Point> {
@override
final typeId = HiveUtils.POINT_TYPE_ID;
@override
Point read(BinaryReader reader) => Point(reader.readInt(), reader.readInt());
@override
void write(BinaryWriter writer, Point obj) {
writer
..writeInt(obj.x)
..writeInt(obj.y);
}
} and everything works fine now. |
I had the same issue. But the name of my hive box was about 30 characters long. I don't remember what's the length exactly. I had changed the name to make it shorter and it helped |
This probably isn't the problem for everybody, but I was running into this error when I was writing null values in my adapter. I think it was throwing off the pointer. What I THINK was happening was I was saving an index of an item with writeInt(), but sometimes my objects didn't have the index set yet, so it was writing null. Then when I was reading them back with readInt(), it was reading my int value with wild results e.g. "-9038923489". Then the next read would result in this error because there were no terminating bytes for the String data it was trying to read. I fixed this by changing my readInt() to just read() and my writeInt() to just write(). Not quite as clean, it'd be nice if there was some null handling built into those specific data type functions, but I can also do it on my end. |
Well, that seems to be an important feature since when I change the structure of the hive class my users have to reinstall the app.... |
Not necessarily, you could change the |
It's a known feature (not a bug) of serialization in software engineering. You have to be careful when modifying serializers (aka: adapters in hive). It's not a bug because it's how object serializers works. Try modifying some bytes of an executable files in your operation system and try running it. It will be probably crashed because OS couldn't understand executable binary. If you need dynamic schemes, I would suggest storing your data in json files or checking updating a class part of hive documentation. |
I edited my comment to use better words. You made an excellent work and I really appreciate that. Thank you very much |
I think you didn't get what I meant. You have to follow those rules to update classes safely - without requiring re-installation. If you don't follow them then the updated adapter would not deserialize previously written data and throw RangeError.
In short, just increase HiveField id when changing field type or adding a new fields and never use removed field's IDs. |
I've tried all solutions on this feed, none of those worked. But I've found a solution in my case, maybe this will help others. I've migrated my project to null safety, and before that Hive was working properly and this error never appears. I've to duplicate my project and try to find the error by elimination. I have one object extending HiveObject, let's call it "Village". Person is an abstract class (BTW no need to put HiveType and HiveField for abstract classes, but you need to put them for classes that extend this abstract class). One of the classes extending Person is intentionally empty. Let's call it "SubPerson": @HiveType(typeId: 8)
class SubPerson extends Person {} Well before migrating my project to null safety, build runner was generating adapters and the reader for SubPerson was like this: @override
SubPerson read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return SubPerson();
} After migrating, build runner generated the same adapter but like this: @override
SubPerson read(BinaryReader reader) {
return SubPerson();
} The error was caused by this method. @themisir you should take a look at this |
@leisim isn't Hive itself skipping to the next Frame if bytes have not read? |
I removed read and write stubs for empty classes after this issue #638. I might have to look at Hive internals to check what's going on. |
@RobinLbt what about the |
Ah you're right. This issue will happen when you're using the model inside another model. Hadn't think that way. |
I had this problem when changing the model shape (add new value). The data on disk still does not have the new value so it throw an error; Workaround
|
Hello, @anandsubbu007 @themisir I've also faced this issue when my one of the auto-generated model class (TypeAdapter) is modified manually and also when the original model class is modified and auto-generated classes are not generated again. So when I run the command |
i have same issue happened when restart app in Android and iOS.
|
I created custom
|
Same as @matsushitak very surprisingly, the method writer.write(xx) doesn't seem to handle rightly the given type. You have to use the specialized method or you will hit the RangeError mark. |
Well indeed, read/write and read$Type/write$Type does slightly different things. The issues in your cases caused because you've written data using |
Thank you for the explanation! I added a warning in the docs to help people with this possible culprit. |
Just thinking, but it could be interesting to add a more complex scenario in the "manual adapter" chapter. |
@roubachof Can you link where you put the warning? |
@themisir Is there actually any reason why the behavior is different? And which is the preferred one for which use case? |
|
The problem is in the generated adapter, Make sure you regenerate adapter if you changed hive object structer |
For me worked the following: Take a look at the Adapter implementation. For me it looked like that.
But it should have looked like that.
Solution
|
Tanks @siddhantsatpute this solution it's work for me |
Fixed this problem yesterday with Edit: but then I did a re-build and the error is back. |
I have the same problem. Each time I have to delete the local data. Have you managed to find a solution? |
i am facing same issue not solve yet . check many article and solution but still same . |
Error: RangeError: Not enough bytes available. due to this error package is useless for me . |
I faced the same issue when using new sealed classes, or more specifically empty classes. Assuming the following hierarchy: sealed class A {
const A();
}
@HiveType(typeId: 3)
class B extends A {
const B();
}
@HiveType(typeId: 2)
class C extends A {
final int field;
const C(this.field)
} The generated adapter for the empty class (here B read(BinaryReader reader) {
return B();
} However, the code should look as follows: B read(BinaryReader reader) {
reader.readyByte(); // Consume written byte
return B();
} Notice the added line This issue may also occur in other cases when the constructor parameters are not empty. There is also another issue #1081 which may be related. |
I am getting the same error while launching the app second time. Any fix for this |
The text was updated successfully, but these errors were encountered: